/k

heroku like git PAAS

Primary LanguageGo

k

heroku like git based deployment. with https server. and systemd.

  • deployment is handled via git push + a git.update hook on the server running <app>.Build
  • services and logs are handled by systemd
  • http(s) server using letsencrypt autocert
  • secrets are encrypted using nacl/secretbox

For more, check out the example config and the generated output

$ k init server
Inited k in ./server
Please enter a password:
Enter password again:

$ k deploy example
Copying k binary to server...
Pushing server:
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: + git switch --detach a3abc8e1b0f3844934ef80af8233a3d2aa4388d8
remote: HEAD is now at a3abc8e encrypted value
remote: + /opt/k/.k generate /run/k
remote: + systemctl daemon-reload
To ssh://localhost:/receive//opt/k/.config
 * [new branch]      master -> 1650494726
Pushing blog:
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: + git switch --detach 7213da913e68c6ade44f00aca0503299407f3b81
remote: HEAD is now at 7213da9 drafty
remote: + PATH=/root/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
remote: + echo Hello world
remote: + systemctl daemon-reload
remote: + systemctl restart k-http.target example.target
To ssh://localhost:/receive//opt/k/example
 * [new branch]      master -> 1650494727

$ k logs example
-- Logs begin at Tue 2022-04-19 20:56:36 CEST, end at Thu 2022-04-21 00:47:04 CEST. --
[...]

$ k status k
● k.target
     Loaded: loaded (/run/systemd/generator/k.target; generated)
     Active: active since Thu 2022-04-21 00:45:28 CEST; 2min 13s ago

Apr 21 00:45:28 localhost systemd[1]: Reached target k.target.

● example.target
     Loaded: loaded (/run/systemd/generator/example.target; generated)
     Active: active since Thu 2022-04-21 00:45:28 CEST; 2min 13s ago

Apr 21 00:45:28 localhost systemd[1]: Reached target example.target.

● k-http.target
     Loaded: loaded (/run/systemd/generator/k-http.target; generated)
     Active: active since Thu 2022-04-21 00:45:28 CEST; 2min 13s ago

Apr 21 00:45:28 localhost systemd[1]: Reached target k-http.target.

● k-https.socket
     Loaded: loaded (/run/systemd/generator/k-https.socket; generated)
     Active: active (running) since Thu 2022-04-21 00:45:28 CEST; 2min 13s ago
   Triggers: ● k-http.service
     Listen: [::]:443 (Stream)
      Tasks: 0 (limit: 2274)
     Memory: 0B
     CGroup: /system.slice/k-https.socket

Apr 21 00:45:28 localhost systemd[1]: Listening on k-https.socket.

● k-http.socket
     Loaded: loaded (/run/systemd/generator/k-http.socket; generated)
     Active: active (running) since Thu 2022-04-21 00:45:28 CEST; 2min 13s ago
   Triggers: ● k-http.service
     Listen: [::]:80 (Stream)
      Tasks: 0 (limit: 2274)
     Memory: 28.0K
     CGroup: /system.slice/k-http.socket

next

  • how to run integration tests in ci
  • implement just enough git to deploy without shelling out (init, push, receive, checkout, …)
  • livereload fileserver with proxy
  • status and logs
    • filter and limit lines
    • show in pager
    • exclude k-http lines. could filter by K=$app to get all related to app and _SYSTEMD_SLICE=k-$app to filter just for self
  • encryption uses a hardcoded salt for the key derivation. figure out whether that’s safe for real
  • k.yaml
    • systemd unit defaults
    • default variables
  • vm management
    • ssh: ssh-copy-id + sshd config
      # comment out the following in /etc/pam.d/sshd to speed up initial connection time
      # (on my machine: ~1.5s -> 0.5s)
      #  # session    optional     pam_motd.so  motd=/run/motd.dynamic
      #  # session    optional     pam_motd.so noupdate
      $ sed -i "s/.*PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config
              
    • packages: apt-get + snap + auto-upgrades
    • firewall
    • hostname: edit /etc/hostname
    • ssh-copy-id
    • how to apply server file configuration?
    • is it enough to add a dropin for systemd?
    • should i just allow copying files over and make a backup of the original file?
  • systemd
    • slices for resource limits on apps - could be used for automatic resource usage dashboards
    • watchdog wrapper executable for health checks
    • loadcredentials & env files for secrets

fun facts

  • debugging systemd is much more fun with transient units - e.g. sudo systemd-run --wait -t -p "BindPaths=/etc:/app" -- bash -c "ls /app /tmp"

unsorted notes

  • Use LoadCredentials for secrets: systemd/systemd#22754
    • Inline environment variables don’t work (systemctl cat ignores permissions)
    • EnvFile still has problem of leaking to child processes. Env vars just don’t seem to be best practice after all…
      • see Environment= […] environment variables are not suitable for passing secrets […]
  • systemd overrides can be applied to slices as defined by the unit name split at - - i.e. k-http.service would read the overrrides k/.service and -/.service. For now I think I want defaults rather than overrides and some app-specific configuration - e.g. LogExtraFields should contain the app/target name, not the unit name