90 lines
5.6 KiB
Markdown
90 lines
5.6 KiB
Markdown
# Immich Restore Test Plan
|
|
|
|
## Ziel
|
|
|
|
Nachweisen, dass `immich.dump` aus dem produktiven Borg-Archiv in einer isolierten Testumgebung wieder einspielbar ist und Immich-Server damit anlaufen, einloggen und Asset-Metadaten anzeigen kann.
|
|
|
|
Bewusst **nicht** Teil dieses Tests:
|
|
|
|
- Wiederherstellung produktiver Foto-Dateien aus `/mnt/user/photos/immich` und `/mnt/user/photos/family_archive`. Der Smoke-Test bleibt DB-/UI-zentriert.
|
|
- Machine-Learning-Container. Spart Image-Pull-Zeit und Resource-Last; ML-Features sind im Smoke-Test nicht erforderlich.
|
|
- Echte Browser-Login-Sequenz. Smoke-Test prueft nur, dass die Login-Seite ausgeliefert wird und die DB-Tabellen `asset` und `"user"` lesbar sind.
|
|
|
|
## Quelle
|
|
|
|
- Backup-Quelle: produktives Borg-Archiv (`hetzner_borg_appdata_critical` oder lokales Mirror)
|
|
- fachlich relevanter Dump im Archiv:
|
|
- `local/borg-dumps/latest/immich.dump`
|
|
- Erzeuger: `ops/borg-ui/scripts/pre-backup-dumps.sh`, Funktion `dump_pg_db immich_postgres ... immich immich` mit `pg_dump -Fc`
|
|
- produktive Foto-Pfade werden im Smoke-Test bewusst **nicht** angefasst
|
|
|
|
## Test-Ziel
|
|
|
|
- Restore-Lab: `/mnt/user/backups/restore-lab/immich`
|
|
- Testdatenpfade:
|
|
- `/mnt/user/backups/restore-lab/immich/postgres` (Test-Postgres-Datadir)
|
|
- `/mnt/user/backups/restore-lab/immich/upload` (leeres Upload-Volume, Immich-Server braucht den Pfad nur als Mountpoint)
|
|
- `/mnt/user/backups/restore-lab/immich/dumps/latest/immich.dump` (extrahierter Dump)
|
|
- Testcontainer:
|
|
- `restoretest-immich-server`
|
|
- `restoretest-immich-postgres` (`ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0` - identisch zur Produktion, weil VectorChord-Backups ein Image mit VectorChord brauchen)
|
|
- `restoretest-immich-redis` (`redis:8.8.0-alpine`, rebuildbar)
|
|
- Testport Web: `127.0.0.1:12283:2283`
|
|
- Report-Ziel: `/mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md`
|
|
|
|
## Schutzregeln
|
|
|
|
- produktive Pfade `/mnt/user/photos/immich` und `/mnt/user/photos/family_archive` werden **nicht** in den Test-Container gemountet
|
|
- produktive Domain `immich.kaleschke.info` wird **nicht** uebernommen
|
|
- keine Traefik-Labels fuer die Testinstanz
|
|
- keine produktive `immich_postgres`-/`immich_redis`-Instanz fuer den Test verwenden
|
|
- ML-Container bleibt weg
|
|
- Testcontainer publishen nur auf `127.0.0.1`, nicht auf LAN- oder Tailscale-Interface
|
|
- Borg-Passphrase wird aus `/mnt/user/appdata/secrets/borg_repo_passphrase.txt` gelesen und niemals in Logs, Reports oder Doku geschrieben
|
|
|
|
## Geplanter Ablauf
|
|
|
|
1. Restore-Ziel unter `/mnt/user/backups/restore-lab/immich` vorbereiten (postgres, upload, dumps/latest)
|
|
2. `local/borg-dumps/latest/immich.dump` aus dem aktuellsten Borg-Archiv extrahieren
|
|
3. Test-Postgres (Immich-Postgres mit VectorChord) und Test-Redis mit `ops/restore-tests/immich-compose.test.yml` starten
|
|
4. `immich.dump` in Test-Postgres importieren (`pg_restore -Fc --clean --if-exists --no-owner --no-privileges`)
|
|
5. Testinstanz `restoretest-immich-server` starten
|
|
6. lokalen Smoke-Test gegen `http://127.0.0.1:12283` ausfuehren und Asset/User-Count aus DB lesen
|
|
7. Report unter `/mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md` schreiben
|
|
8. Testcontainer stoppen und Restore-Lab bereinigen
|
|
|
|
## Smoke-Test
|
|
|
|
Minimal erfolgreich:
|
|
|
|
- Test-Postgres startet `healthy`
|
|
- `pg_restore -Fc` laeuft ohne Fehler durch
|
|
- Immich-Server liefert HTTP `200`, `302` oder `303` auf `/`
|
|
- Response enthaelt mindestens einen der Marker `Immich`, `Login`, `Signin`
|
|
- `select count(*) from asset;` und `select count(*) from "user";` sind lesbar
|
|
|
|
Optional spaeter:
|
|
|
|
- Echte Login-Form via API ansprechen
|
|
- VectorChord-/pgvector-Extensions explizit per `\dx` pruefen
|
|
- Test mit gemountetem **read-only** Foto-Sample-Pfad und Thumbnail-Rendering
|
|
- Test inkl. ML-Container, sobald genug Test-Ressourcen verfuegbar
|
|
|
|
## Bekannte Komplikationen
|
|
|
|
| Risiko | Beschreibung | Mitigation |
|
|
|---|---|---|
|
|
| Dump-Groesse unbekannt | `pg_dump -Fc` der Immich-DB kann je nach Asset-/Face-Tabellen mehrere GB sein | Erster Lauf bewusst mit `--what-if`, anschliessend Operator-Test mit Zeitmessung |
|
|
| `pg_restore`-Dauer unbekannt | Index-/Constraint-Aufbau und VectorChord-Index-Build koennen lange dauern | Test-Postgres mit Health-Polling startet; Lauf nicht abbrechen ohne `pg_restore`-Exit |
|
|
| VectorChord-/pgvector-Extension-Mismatch | Wenn das Test-Postgres-Image nicht zu Produktion passt, kann der Restore oder Immich-Start fehlschlagen | Compose pinnt denselben Digest wie `apps/immich/docker-compose.yml` |
|
|
| Immich-Server-Migrations beim Start | Immich fuehrt beim ersten Start DB-Migrations aus; das kann nach Restore noch laufen, bevor Web-UI antwortet | Smoke-Test pollt HTTP bis zu 120 s, bevor er als Fehler markiert |
|
|
| Asset-Files fehlen | Der Test mountet kein Foto-Volume; Immich zeigt "missing" auf Asset-Detail-Seiten | Smoke-Test prueft nur Login-Page und DB-Counts, nicht Asset-Rendering |
|
|
| ML-Endpoint unreachable | Immich-Server kann ML-Endpoint nicht erreichen | `IMMICH_MACHINE_LEARNING_URL` zeigt bewusst auf einen nicht erreichbaren Hostnamen; Login bleibt funktional, ML-Features bleiben deaktiviert |
|
|
|
|
## Noch offen vor dem ersten echten Lauf
|
|
|
|
- Dump-Groesse `immich.dump` auf dem Host bestimmen (`ls -lh /mnt/user/backups/borg/dumps/latest/immich.dump`)
|
|
- Erwartete Restore-Dauer durch ersten Lauf mit `--keep-data` messen
|
|
- Pruefen, ob die Immich-Tabellen `assets`/`users` im aktuellen Schema noch existieren (Schema-Drift bei Major-Update wuerde die Asset-Count-Query brechen, das Skript faengt das tolerant ab)
|
|
- Schedule-Eintrag in `ops/restore-tests/schedule.md`: aktuell ist Immich nur als "spaeter, eigener Sprint" gefuehrt. Erst nach erstem erfolgreichen Lauf in Schedule aufnehmen, z. B. quartalsweise.
|