Deployment-Demo v3
Gemeinsames Staging — neu gebaut bei jedem Push auf main
Live-Ticker — Deploy ohne Lücke
Der Ticker fragt zweimal pro Sekunde /health ab und zeigt an, welcher Container antwortet. Jetzt einen Commit pushen und zusehen: die Container-Kennung wechselt, ohne dass ein Punkt rot wird. kamal-proxy schaltet erst um, wenn der neue Container gesund ist. Ohne das hiesse jeder Deploy: ein paar Sekunden Verbindungsfehler.
Gästebuch — Zustand überlebt den Deploy
Die Einträge liegen in PostgreSQL, einem eigenen Container neben der App (Kamal-Accessory), dessen Daten auf dem Server-Volume liegen. Jeder Eintrag trägt die Version, die ihn geschrieben hat — alte Einträge aus längst ersetzten Containern sind immer noch da. Das ist der Unterschied zwischen einem Deploy und einem Datenverlust.
Zwei Ablagen — nur eine überlebt
Der Knopf legt dieselbe Notiz zweimal ab: links auf dem eingehängten Volume, rechts im Dateisystem des Containers. Nach dem nächsten Deploy existiert nur noch die linke Liste. Genau dieser Unterschied ist der häufigste Produktions-Unfall — Uploads, die im Container lagen und mit ihm starben. Das Go-live-Audit sucht exakt danach.
Volume (bleibt)
Container (stirbt)
Health-Schalter — krank geht nicht live
Der Schalter legt eine Marke auf dem Datenvolume ab — auch ein frisch deployter Container liest sie und meldet sich krank. Die Folge: der nächste Deploy bleibt stehen, weil kamal-proxy einen Container ohne gesunden Healthcheck nie live schaltet — die alte Version läuft einfach weiter. Diese Seite bleibt dabei erreichbar; krank ist nur der Healthcheck. Reparieren, erneut deployen, alles läuft.
Langsame Anfrage — niemand wird abgerissen
Der Knopf startet eine Anfrage, die 20 Sekunden braucht. Währenddessen deployen: der alte Container bekommt SIGTERM, nimmt nichts Neues mehr an — aber diese Anfrage darf fertig werden, erst dann stirbt er (Kamal wartet beim Stoppen 30 s). Ohne sauberes SIGTERM-Handling würde jeder Deploy laufende Anfragen mitten im Satz kappen.
Start-Historie — jeder Deploy hinterlässt eine Zeile
Bei jedem Prozessstart trägt sich die App mit Version und Container-Kennung in die Datenbank ein. Die Liste ist die Deploy-Geschichte dieses Stands — und der Beleg, dass all die Container kamen und gingen, während die Daten blieben.
Backup — läuft nachts, meldet sich hier
Ein Backup, das niemand sieht, ist ein Gerücht. Der Backup-Container sichert die Datenbank jede Nacht und legt seinen letzten Stand als Datei aufs Volume — die Seite zeigt ihn ungefiltert. Wiederherstellung ist eine dokumentierte Übung (restore.sh), keine Improvisation.