Für wen es ist
Sie liefern ein Go-Binary auf einen Server aus und betreiben es unter systemd. Ihr Deployment besteht heute aus scp, systemctl restart und einem kurzen Blick ins Log. Das geht gut, bis ein Neustart in eine geschäftige Minute fällt und Caddy ein paar Sekunden lang 502 liefert. Oder bis Sie einen Build ausrollen, der sauber startet und dann jede Anfrage scheitern lässt, und nichts verhindert, dass er den Traffic bekommt.
Dieses Kit ersetzt das durch ein Deploy-Skript, das das neue Release neben dem alten startet, es prüft, bevor es Traffic erhält, umschaltet und von selbst zurückgeht, wenn das neue Release schlecht wird. Es ist das Gegenstück in Go und systemd zu unserem Kit für Node und pm2, für Leute, die kein pm2 betreiben und auch keins wollen.
Das bekommen Sie
deploy.sh: Release-Ordner mit einem atomarencurrent-Symlink, Deployment eines in der CI gebauten Binarys oder eines Builds auf dem Server, Health Checks (N Antworten in Folge), Umschalten, Drain, automatisches Rollback,deploy.sh rollbackund ein Lock, damit sich zwei Deployments nicht überschneiden.- Gehärtete systemd-Units:
Type=notify, Graceful Stop, Restart-Policy, ein unprivilegierter Benutzer, Secrets in einer env-Datei mit Modus 600, die der Service-Benutzer nicht lesen kann. - Ein Installer, der Benutzer, Verzeichnisse, Units und die env-Datei einrichtet.
- Eine kleine Beispiel-App in Go (nur Standardbibliothek) mit Graceful Shutdown und einem getesteten Helfer für Socket Activation und
sd_notify. - Alarme per Telegram oder Webhook, wenn ein Deployment fehlschlägt. Erfolgreiche Deployments bleiben still.
- Ein Test-Harness und die Ausgabe seines letzten Laufs.
Zwei Wege zum Umschalten
Blue/Green (der Standard). Zwei Instanzen, app@a und app@b, stehen hinter Caddy. Das neue Release startet auf dem freien Port und muss den Health Check mehrmals in Folge beantworten, bevor Caddy davon erfährt. Dann lädt Caddy graceful neu, die alte Instanz läuft per Drain aus und stoppt. Wird das neue Release nach dem Umschalten krank, stellt das Skript alles zurück. Das Rollback ist dieselbe Bewegung rückwärts, und mit KEEP_PREVIOUS=1 bleibt die alte Instanz warm, sodass ein Rollback nur ein Caddy-Umschalten ist.
Socket Activation. systemd hält den lauschenden Socket offen, während der Service neu startet, Verbindungen werden also eingereiht statt abgelehnt. Das neue Release läuft zuerst als Canary auf einem anderen Port, ein kaputter Build erreicht den Restart also gar nicht erst.
Blue/Green ist der Standard, weil dabei die langsamste Anfrage nahe an der Dauer der Anfrage selbst bleibt. Der Socket-Modus ist für Fälle gedacht, in denen Sie nicht zwei Instanzen betreiben können: ein fester Port, den Sie nicht verschieben können, oder eine Ressource, die nur ein Prozess halten darf. Die Messungen unten decken beide ab.
Gemessen
Aufbau: ein Debian-12-Container mit systemd 252 als PID 1, Caddy 2.6.2, eine Beispiel-App, die 1.5 s zum Starten braucht, konstant 20 Anfragen pro Sekunde durch Caddy, drei Läufe pro Szenario. Eine Anfrage zählt als fehlgeschlagen bei jedem Verbindungsfehler, Timeout oder Status außer 200.
| Szenario | Gesendet | Fehlgeschlagen |
|---|---|---|
Einfaches systemctl restart, eine Instanz | 152 bis 162 | 33 bis 42 (alle HTTP 502) |
Dasselbe, mit lb_try_duration 5s in Caddy | 162 | 0, aber die langsamste Anfrage dauerte 2.3 s |
| Blue/Green, gutes Deployment | 293 bis 295 | 0 |
Blue/Green, Release, dessen /health 500 liefert | 458 bis 460 | 0 |
| Blue/Green, Release stürzt beim Start ab | 132 | 0 |
| Blue/Green, Release wird nach dem Umschalten krank | 381 bis 383 | 0 (das schlechte Release beantwortete 182 oder 183 Anfragen vor dem Rollback) |
| Blue/Green, Rollback | 293 bis 295 | 0 |
Blue/Green, Rollback mit KEEP_PREVIOUS=1 | 222 bis 223 | 0, der Traffic wechselte nach 0.1 s |
| Blue/Green, gutes Deployment mit 2 s langen Anfragen in Arbeit | 234 | 0, die langsamen Anfragen liefen durch, wurden nicht abgebrochen |
| Socket-Modus, gutes Deployment | 268 bis 269 | 0 |
| Socket-Modus, gutes Deployment mit 2 s langen Anfragen in Arbeit | 307 bis 310 | 0, langsamste Anfrage 5.65 s |
Ein Deployment dauert im Blue/Green-Modus 8 bis 9 Sekunden, und nach etwa 3.6 Sekunden liegt der Traffic auf dem neuen Release. Das sind die Werte für diese App und diese Maschine.
So läuft ein Deployment ab
Das README geht sieben Schritte durch. Kurz gefasst: Lock nehmen, Release-Ordner anlegen, die freie Instanz starten und auf ihre Bereitschaftsmeldung warten, sie direkt per Health Check prüfen, den neuen Upstream schreiben und Caddy neu laden, den Symlink umlegen, warten, erneut prüfen und erst dann die alte Instanz stoppen. Jeder Schritt hat einen definierten Fehlerpfad, und die wichtigen sind getestet: ein Release, das nicht gesund ist, ein Absturz beim Start und ein Release, das nach dem Umschalten schlecht wird.
Voraussetzungen
Linux mit systemd, Caddy, curl und flock. Go und git nur, wenn Sie auf dem Server bauen. Ein Service auf einem Host.
Häufige Fragen
Ich nutze Node und pm2. Ist das etwas für mich?
Nein, schauen Sie sich das VPS Deploy & Backup Kit an. Es erledigt dieselbe Aufgabe für diesen Stack.
Brauche ich Caddy?
Blue/Green braucht es für das Umschalten. Wir haben beide Modi mit Caddy davor gemessen.
Läuft es auch unter Ubuntu?
Ubuntu nutzt ebenfalls systemd, und das Kit braucht nur systemd und Caddy, es passt also. Getestet wurde es unter Debian 12.
Was macht ein zweites Deployment, solange eines läuft?
Es beendet sich sofort mit Exit-Code 75 und sendet keinen Alarm. Das ist der Lock.
Lizenz
Sie dürfen es auf Ihren eigenen Servern einsetzen. Bitte verkaufen Sie die Dateien nicht weiter.
Änderungsprotokoll
- 0.1.0: erstes Release.
Weiterlesen
- What a plain systemctl restart costs a Go service under load (Englisch)
- systemd socket activation: no dropped requests, but a cost (Englisch)
- Roll back a bad deploy in a minute with release folders (Englisch)
- Database migrations that survive a zero-downtime deploy (Englisch)
- Deploy health checks that catch bad releases (Englisch)
- Caddy blue/green config for a one-server app, line by line (Englisch)
Herunterladen
Zahlung, Steuern und Rechnung übernimmt Polar als Merchant of Record. Den Download-Link erhalten Sie nach dem Checkout.