Files
desfoto/docs/deployment.md

5.5 KiB
Raw Blame History

Deployment — desfoto.de

Zielumgebung

Baustein Wert
Produktionshost prod-main = opencode-prod@87.106.24.138 (NOPASSWD sudo)
Live-Verzeichnis /home/denny/stacks/desfoto/ (Owner denny:denny)
Release-Snapshots /home/denny/stacks/desfoto-releases/<stamp>-<sha>/
Compose-Dateien compose.yml + compose.vps.yml, Projektname desfoto
Container desfoto-web-1 (nginx:1.28-alpine), gebunden an 127.0.0.1:18430
Netzwerk externes Docker-Netzwerk web (Traefik-Docker-Provider)
Reverse Proxy Traefik v3 im Projekt stack (/srv/stack/docker-compose.yml)
Entrypoints http und https, ACME-Resolver le, HTTP-01-Challenge
Zertifikate /srv/traefik/acme.json
Domains desfoto.de (kanonisch) und www.desfoto.de → 301 auf Apex

Der Proxy wird niemals neu gestartet oder neu erzeugt. Die Anbindung erfolgt ausschließlich über Labels in compose.vps.yml.

Ablauf einer Veröffentlichung

/home/king/bin/oc-release /home/king/projects/desfoto \
  "feat: ..." <geänderte Dateien...>

oc-release committet und pusht die genannten Dateien und ruft danach die getrackten Hooks auf:

  1. .ocauto/deploy <sha>

    • prüft, dass HEAD dem Release entspricht und site/, nginx.conf, compose.yml, compose.vps.yml keine uncommitteten Änderungen haben;
    • packt diese Pfade in ein Archiv und lädt es nach prod-main:/tmp;
    • legt auf dem Server zuerst einen Snapshot der aktuell laufenden Version an (/home/denny/stacks/desfoto-releases/<stamp>-<sha>/, zusätzlich als previous verlinkt);
    • entpackt die neue Version nach /home/denny/stacks/desfoto/, setzt den Owner auf denny:denny und schreibt die Release-Kennung nach RELEASE;
    • docker compose -f compose.yml -f compose.vps.yml up -d --remove-orphans und wartet auf healthy;
    • entfernt einmalig die veralteten desfoto.de-Weiterleitungs-Labels aus /srv/stack/docker-compose.yml: Es werden ausschließlich Traefik-Label-Zeilen mit desfoto-Bezug sowie der zugehörige Kommentar entfernt, das Ergebnis wird zuerst als Compose-Projekt validiert (config --quiet) und danach per atomarem mv an die Stelle der Live-Datei gesetzt. Eine Vorher-Fassung liegt im Snapshot (docker-compose.yml.stack-backup) und daneben als docker-compose.yml.bak.<stamp>. Danach wird ausschließlich der landing-Container mit --no-deps neu erzeugt, damit dennyapp.de und dennyschulz.de unverändert weiterlaufen. Bleibt eine desfoto-Referenz übrig (z. B. ein eigener Service-Block), wird sie als WARNUNG ausgegeben.
  2. .ocauto/verify <sha>

    • vergleicht den Dateibaum unter /home/denny/stacks/desfoto/site mit dem committeten site/ (SHA-256 über alle Dateien außer den datierten sitemap.xml/security.txt);
    • prüft alle 13 Routen, die 404-Seite, robots.txt, sitemap.xml, .well-known/security.txt, Bilder und Schriften;
    • prüft die Weiterleitungen http → https und www → Apex;
    • prüft die Sicherheits-Header, dass kein Set-Cookie gesetzt wird und dass das Zertifikat noch mindestens sieben Tage gültig ist;
    • prüft, dass www.dennyschulz.de und dennyapp.de weiterhin erreichbar sind.

Routing

desfoto.de wird vor dem Aufräumen bereits vom neuen Container bedient, weil die Routers in compose.vps.yml eine explizite Traefik-Priorität 200 tragen und die alten Weiterleitungsrouters keine Priorität setzen (damit gilt dort die Regel-Länge). Der Container wird also zuerst gesund geprüft, und erst danach werden die alten Labels entfernt — der Übergang hat damit kein Fenster ohne Antwort.

www.desfoto.de wird über die Middleware desfoto-canonical dauerhaft auf https://desfoto.de/... umgeschrieben. Für http greift die globale Entrypoint-Weiterleitung von Traefik auf https; die ACME-HTTP-01-Challenge beantwortet Traefik selbst, bevor diese Weiterleitung greift.

Rollback

ROLLBACK_TO=/home/denny/stacks/desfoto-releases/<stamp>-<sha> \
  /home/king/projects/desfoto/.ocauto/deploy rollback

Der Befehl synchronisiert site/, nginx.conf und beide Compose-Dateien aus dem Snapshot zurück nach /home/denny/stacks/desfoto/ und startet den Stack neu. Die frühere Version bleibt so lange verfügbar, bis sie bewusst gelöscht wird.

Jeder Release legt den Snapshot an, auch der allererste. Enthält der Snapshot noch kein site/ (weil vorher nichts ausgeliefert wurde), entfernt der Rollback den desfoto-Stack wieder und stellt den Zustand vor der Veröffentlichung her.

Wurde /srv/stack/docker-compose.yml verändert, liegt die Vorher-Fassung sowohl im Snapshot als docker-compose.yml.stack-backup als auch daneben unter docker-compose.yml.bak.<stamp>. Beide werden vom Rollback automatisch zurückgespielt, gefolgt von docker compose up -d --no-deps landing; das Backup .bak.<stamp> bleibt zusätzlich für einen manuellen Eingriff liegen.

Betrieb

ssh prod-main
sudo docker compose -f /home/denny/stacks/desfoto/compose.yml \
                    -f /home/denny/stacks/desfoto/compose.vps.yml ps
sudo docker logs --tail 50 desfoto-web-1
sudo docker inspect --format '{{.State.Health.Status}}' desfoto-web-1

Access-Logs gibt es bewusst nicht (access_log off in nginx.conf). Auch Fehler schreibt nginx nicht weg: error_log /dev/null crit; verwirft sie vollständig, statt sie in eine Datei zu schreiben. Der JSON-Log-Treiber des Containers ist zusätzlich auf 5 MB × 2 Dateien begrenzt. Das entspricht der Zusage in der Datenschutzerklärung.