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>
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/immichvorhanden (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-ifausgefuehrt werden, dann mit--keep-datazur 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.dumpist Teil des letzten Borg-Archivs (siehepre-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_serverContainer mit Imageghcr.io/immich-app/immich-server:release@sha256:c15bff75068effb03f4355997d03dc7e0fc58720c2b54ad6f7f10d1bc57efaa5 - produktive Postgres:
immich_postgresmittensorchord/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.ymlops/restore-tests/immich-restore-test.shops/restore-tests/immich-restore-test.ps1(Scaffold, kein Live-Run)ops/restore-tests/immich-plan.mdops/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 bereitsdown - Restore-Lab-Daten bleiben mit
--keep-dataerhalten; ohne Flag werden sie geloescht
Smoke-Test-Pruefungen
Minimal erwartet im Report:
HTTP status after redirect: 200|302|303Login page marker: okAsset count in test DB: Zahl, odern/abei Schema-DriftUser count in test DB: Zahl, odern/abei 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.shmit 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-dataueberschreibt das). - Borg-Passphrase wird aus Host-Secret-Datei gelesen und nirgendwo geloggt.
ntfywird im ersten echten Lauf nicht eingebunden.