dorfteich/docs/vs-nfd/98-update-rollback-protokoll.md
Claude Fable 5 18239e2fa9
All checks were successful
CD / Deploy to Test (push) Successful in 12s
CD / Smoke tests against Test (push) Successful in 1m15s
CD / Promote to Int (push) Successful in 12s
CI / Lint, typecheck, test (push) Successful in 6m19s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 8m13s
CI / Import/export fidelity gate (push) Successful in 54s
CI / Lint, typecheck, test (pull_request) Successful in 6m20s
CI / Build container images (pull_request) Successful in 1m12s
CI / Auth e2e pack (pull_request) Successful in 8m24s
CI / Import/export fidelity gate (pull_request) Successful in 58s
CD / Build and push images (push) Successful in 22s
#221: offline update path incl. migrations, rehearsed with rollback
Adds docs/operations/update-runbook.md (obtain, verify by digest, back
up, apply, verify, roll back) with the migration behaviour stated
explicitly: a failed migration rolls back its own transaction but is
recorded in _prisma_migrations and blocks every further migrate deploy
(P3009) — including a re-deployed old image — until migrate resolve
--rolled-back; semantically irreversible migrations have exactly one way
back, the pre-update backup set. No rolling updates on a compose stage.
Rehearsed in the isolated environment of #220: regular update to a v2
image set, then a deliberate failed-update (P3018 division by zero,
schema change proven rolled back) with image-rollback-alone shown
insufficient and the documented recovery executed. Protocol:
docs/vs-nfd/98-update-rollback-protokoll.md. ADR 0024 decisions 5+6
recorded as executed; operations handbook and restore runbook updated;
plan checkbox P1-3 ticked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
2026-07-31 17:26:50 +02:00

4.4 KiB

Update-/Rollback-Protokoll — Probe in der isolierten Umgebung (Issue #221)

Nachweis für Maßnahmenplan P1-3 (ADR 0024): der Update-Pfad inklusive Migrationen und geprobtem Fehlschlag-Rollback, ausgeführt in derselben netzisolierten Umgebung wie der Isolationslauf (97-isolationslauf-protokoll.md — Compose-Projekt dorfteich-isolated, alle Netze internal: true, kein Egress-Pfad). Belegstufe: live verifiziert. Die daraus destillierte Prozedur steht in docs/operations/update-runbook.md.

  • Datum: 2026-07-31
  • Ausgangsstand („v1"): Images dorfteich-iso-*:isolated (main@a758c9d, backup mit #288-Fix aus 4f6596e), Instanz mit Inhalt aus dem Isolationslauf.
  • Update-Ziel („v2"): Images dorfteich-iso-*:isolated-v2, gebaut aus dem Kettenstand ccffcaa (#288 + #220) — als Stellvertreter eines regulären Release-Bundles; die Beschaffung/Digest-Prüfung eines echten Bundles ist das Mirror-Verfahren (#218, 95-mirror-protokoll.md) und wurde dort bereits nachgewiesen.
  • Fehlschlag-Kandidat („bad"): api-Image mit einer absichtlich fehlschlagenden Migration (20260731230000_deliberately_failing_update: ALTER TABLE + SELECT 1/0), nur für die Probe gebaut, nie committet.

Phase A — reguläres Update

Schritt Ergebnis
Pre-Update-Backup Set 20260731-150833 über die Admin-API erzeugt und in der Set-Liste bestätigt
TAG → v2, up -d alle vier eigenen Services zusammen ersetzt (Ausfallfenster Sekunden, kein Rolling Update)
Migrationen migrate-on-start läuft durch (dieses „Release" enthält keine neuen Migrationen)
/readyz vollständig grün
Inhalt Seite „Isolationstest Seite" unverändert vorhanden

Phase B — geprobter Fehlschlag + Rollback

  1. Bad-Update einspielen (TAG → bad, up -d): api scheitert beim Boot in migrate deployP3018, ERROR: division by zero bei 20260731230000_deliberately_failing_update; Container geht in den Restart-Loop, jeder Folge-Boot meldet P3009 („migrate found failed migrations").
  2. Datenbank-Zustand geprüft: die Migration steht als failed in _prisma_migrations (Logs erfasst), aber broken_column existiert nicht — die per-Migration-Transaktion hat den Schema-Eingriff zurückgerollt. Genau das dokumentierte Verhalten.
  3. Image-Rollback allein reicht nicht (bewusst vorgeführt): TAG zurück auf v2, up -d — der alte Stand scheitert weiter mit P3009 („The 20260731230000_deliberately_failing_update migration started at 2026-07-31 15:10:50 UTC failed").
  4. Recovery wie im Runbook: migrate resolve --rolled-back 20260731230000_deliberately_failing_update (im api-Image ausgeführt) → „marked as rolled back" → api-Neustart: /readyz vollständig grün, Inhalt unverändert, Migrations-Row trägt rolled_back_at.
  5. Alternativer Weg zurück (für semantisch irreversible, aber erfolgreich gelaufene Migrationen): Restore des Pre-Update-Sets — der Restore-Pfad selbst ist im Isolationslauf verifiziert (97-isolationslauf-protokoll.md, Fix #288).

Versions-Skew (Akzeptanzkriterium)

Ein Compose-Stage kennt kein Rolling Update: docker compose up -d ersetzt web/api/collab/backup zusammen; Mischbetrieb alter und neuer Versionen ist kein unterstützter Betriebszustand und dauert nur die Container-Ersetzung selbst (Sekunden). Für VS-Zonen heißt das: Update im angekündigten Wartungsfenster; die Migrationen wendet ausschließlich der neue api-Container beim Start an (MIGRATE_ON_START).

Rückfluss

  • docs/operations/update-runbook.md — die Prozedur (Beschaffen, Prüfen, Sichern, Einspielen, Verifizieren, Rollback) inkl. explizitem Migrationsverhalten; aus dieser Probe destilliert.
  • docs/operations/restore-runbook.md — Querverweis: Restore als einziger Weg zurück nach irreversiblen Migrationen.
  • #229 — Betriebshandbuch §1 (Airgap) und §2 (Update/Rollback) verweisen auf Runbook und dieses Protokoll.