Files
homelab-infra/ops/restore-tests/immich-runbook.md
T
Micha 67ec40b762 Docs sweep: reflect Komodo bootstrap first run + clean stale "still open" notes
Six files had outdated status notes that the F-09 first run on
2026-05-30 made wrong:

- ops/restore-tests/komodo-bootstrap-runbook.md: "Erster echter Lauf
  steht noch aus" -> first run confirmed
- ops/restore-tests/komodo-bootstrap-plan.md: "Noch offen vor dem
  ersten echten Lauf" section -> "Bestaetigte Laeufe" table with
  the --what-if and --keep-data runs
- ops/restore-tests/immich-runbook.md: status note still said
  "Erster echter Lauf steht noch aus" although the Immich first run
  was 2026-05-27; correcting in the same sweep
- docs/AUDIT_2026-05-25_TODO.md: Sprint 2 entry on Komodo bootstrap
  path no longer carries the "Trockenlauf-Skript bleibt als offene
  Folgeaufgabe" tail
- docs/SERVICES_RECOVERY.md: replaced the "Trockenlauf-Idee (Doku-only,
  nicht ausgefuehrt)" section with the confirmed repo-script flow and
  marked the two "Naechste Aufgaben" rows about the dry-run as done
- docs/RESTORE_DRILL_ROUTINE.md: Q2 2026 DR-Sanity-Check entry now
  splits Komodo-Bootstrap-Pfad (done) from the two still-open items
  (Gitea bundles, secrets inventory)

No behavior change, only documentation consistency.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 11:18:37 +02:00

6.1 KiB

Immich Restore Runbook

Status

Skript und Test-Compose sind vorbereitet. Erstlauf 2026-05-27 erfolgreich (SUCCESS, HTTP 200, 11977 Assets im Test-DB-Check). Report: /mnt/user/backups/restore-reports/immich-2026-05-27.md. Folgelaeufe je Quartal gemaess docs/RESTORE_DRILL_ROUTINE.md (Q2 = Immich).

Vor dem ersten Lauf muss Operator entscheiden:

  • ist genug freier Platz unter /mnt/user/backups/restore-lab/immich vorhanden (Dump + Test-Postgres-Datadir + Upload-Dummy)?
  • ist genug freier RAM/CPU verfuegbar, um Immich-Server + Test-Postgres parallel zur produktiven Last laufen zu lassen?
  • soll der Lauf zuerst mit --what-if ausgefuehrt werden, dann mit --keep-data zur Zeitmessung?

Vorbedingungen

  • Borg-Quelle ist verfuegbar
  • Borg-UI laeuft (docker ps | grep borg-ui)
  • Borg-Passphrase-Datei vorhanden: /mnt/user/appdata/secrets/borg_repo_passphrase.txt
  • aktueller Dump immich.dump ist Teil des letzten Borg-Archivs (siehe pre-backup-dumps.sh)
  • Testpfade unter /mnt/user/backups/restore-lab/ und /mnt/user/backups/restore-reports/ sind freigegeben
  • produktiver Immich-Stack laeuft (oder ist bewusst aus); der Test ist davon unabhaengig

Bestaetigter Host-Stand (Soll)

  • produktiver Immich-Server: immich_server Container mit Image ghcr.io/immich-app/immich-server:release@sha256:c15bff75068effb03f4355997d03dc7e0fc58720c2b54ad6f7f10d1bc57efaa5
  • produktive Postgres: immich_postgres mit tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
  • produktive Foto-Pfade: /mnt/user/photos/immich, /mnt/user/photos/family_archive
  • aktueller Dump-Pfad: /mnt/user/backups/borg/dumps/latest/immich.dump
  • Secret: /mnt/user/appdata/secrets/immich_postgres_password.txt (wird vom Test nicht gebraucht; Test nutzt eigenes Test-Passwort)

Bestaetigter Teststand

  • noch kein echter Mini-Restore gelaufen
  • Skript-Set vorbereitet:
    • ops/restore-tests/immich-compose.test.yml
    • ops/restore-tests/immich-restore-test.sh
    • ops/restore-tests/immich-restore-test.ps1 (Scaffold, kein Live-Run)
    • ops/restore-tests/immich-plan.md
    • ops/restore-tests/immich-runbook.md

Erster Lauf - trockene Variante

bash /mnt/user/services/homelab-infra/ops/restore-tests/immich-restore-test.sh --what-if

Erwartete Ausgabe: nur Plan-Output, kein Docker-Start, kein Borg-Extract.

Erster Lauf - echter Test (Operator-freigegeben)

# Optional: laufende Borg-Jobs pruefen, damit Borg-UI nicht parallel ausgelastet ist
docker exec borg-ui sqlite3 /data/borg.db \
  "select status, archive_name, datetime(updated_at,'unixepoch') from backup_jobs order by id desc limit 5;"

# Lauf mit Datenerhalt fuer Zeitmessung
bash /mnt/user/services/homelab-infra/ops/restore-tests/immich-restore-test.sh --keep-data

Bei erfolgreichem Lauf:

  • Report unter /mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md
  • Test-Container restoretest-immich-* sind nach Lauf bereits down
  • Restore-Lab-Daten bleiben mit --keep-data erhalten; ohne Flag werden sie geloescht

Smoke-Test-Pruefungen

Minimal erwartet im Report:

  • HTTP status after redirect: 200|302|303
  • Login page marker: ok
  • Asset count in test DB: Zahl, oder n/a bei Schema-Drift
  • User count in test DB: Zahl, oder n/a bei Schema-Drift
  • Pre-Dump-Hook-Kette (pg_dump -Fc) und Restore-Kette (pg_restore -Fc) sind kompatibel
  • pgvecto-rs Extension ist im Restore-DB sichtbar

Manuelle Folgepruefung (optional):

Das Skript stoppt die Test-Container auch bei --keep-data; dieses Flag erhaelt nur die Restore-Lab-Daten. Fuer eine manuelle Folgepruefung nach einem erfolgreichen --keep-data-Lauf die Testinstanz kurz wieder hochfahren und danach wieder stoppen:

docker compose -f /mnt/user/services/homelab-infra/ops/restore-tests/immich-compose.test.yml up -d \
  restoretest-immich-postgres restoretest-immich-redis restoretest-immich-server

docker exec restoretest-immich-postgres psql -U immich -d immich -c "\dx"
docker exec restoretest-immich-postgres psql -U immich -d immich -tAc "select count(*) from assets;"
docker logs --tail 100 restoretest-immich-server

docker compose -f /mnt/user/services/homelab-infra/ops/restore-tests/immich-compose.test.yml down

Cleanup nach Lauf ohne --keep-data

Das Skript bereinigt:

  • Test-Container via docker compose down
  • Restore-Lab unter /mnt/user/backups/restore-lab/immich
  • Extract-Cache unter /mnt/user/appdata/borg-ui/restore/immich-extract

Vorsicht: rm -rf arbeitet ausschliesslich auf dem festen Restore-Lab-Pfad. Produktive Immich-Pfade unter /mnt/user/photos/* werden vom Skript niemals beschrieben.

Fehlerfaelle

Symptom Ursache Massnahme
pg_restore: error: could not find extension ... vectors Test-Postgres-Image nicht pgvecto-rs Compose-Pin im Test-Compose pruefen
HTTP-Timeout nach 120 s Immich-Migrations laufen noch Wartezeit im Skript erhoehen oder Logs pruefen
pg_isready nie healthy Test-Postgres bricht beim Start ab (Datadir-Konflikt) Restore-Lab vor Lauf vollstaendig leer; docker logs restoretest-immich-postgres
Body matcht keine Marker Immich UI hat sich versioniert; Marker-Liste anpassen Marker im Skript erweitern (grep -qiE)
Disk-Space-Mangel Dump + Postgres-Datadir + Extract-Cache mehr Platz freigeben oder Lauf abbrechen

Schedule-Eintrag (geplant, noch nicht aktiv)

Aktuell in ops/restore-tests/schedule.md nur als "spaeter, eigener Sprint" gelistet.

Nach erstem erfolgreichen Lauf vorschlagen:

  • quartalsweise (0 9 1 1,4,7,10 * o. ae.)
  • ohne --keep-data
  • Report wird automatisch von monthly-random-restore.sh mit eingelesen, sobald Immich dort eintragbar ist

Festgelegte Entscheidungen

  • Immich-Restore-Test nutzt isoliertes Test-Postgres mit gleichem Image wie Produktion.
  • ML-Container wird im Smoke-Test nicht mitgestartet.
  • Produktive Foto-Pfade werden nicht in den Test gemountet.
  • Test-Daten werden nach erfolgreichem Lauf geloescht (--keep-data ueberschreibt das).
  • Borg-Passphrase wird aus Host-Secret-Datei gelesen und nirgendwo geloggt.
  • ntfy wird im ersten echten Lauf nicht eingebunden.