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
- 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?
- ssh: ssh-copy-id + sshd config
- 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
- 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"
- 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 […]
- Inline environment variables don’t work (
- 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