Prepare Immich restore smoke test

This commit is contained in:
2026-05-26 21:33:01 +02:00
parent 48099fb48d
commit c5d231a0db
14 changed files with 616 additions and 8 deletions
+2 -2
View File
@@ -55,13 +55,13 @@ Kontext bewusst gesichert, bevor weitere Live-Aenderungen passieren:
| offen | Disk- und Share-TBDs eintragen | Modelle, Groessen, Seriennummern, Filesysteme und Cache-Settings sind dokumentiert |
| erledigt (Skript + Host-Test) | Gitea-Repo-Mirror-Mechanik definieren | `ops/borg-ui/scripts/gitea-bundle-mirror.sh` erzeugt verifizierte Bundles unter `/mnt/user/backups/git-bundles/gitea`; Host-Erstlauf 2026-05-26: 4 Bundles, Checksums OK, `homelab-infra.bundle` klonbar und `git fsck` sauber; Schedule bleibt offen |
| offen | Komodo-Bootstrap-Pfad beschreiben | Kaltstart ohne laufendes Komodo ist dokumentiert |
| offen | Immich-Restore-Test planen | Testumfang, Datenpfade und Smoke-Test-Kriterium stehen fest |
| erledigt | Immich-Restore-Test planen | Testumfang, Datenpfade und Smoke-Test-Kriterium sind in `docs/IMMICH_RESTORE_TEST.md`, `ops/restore-tests/immich-plan.md` und `ops/restore-tests/immich-runbook.md` festgehalten; erster Host-Lauf bleibt offen |
## Sprint 3 - Restore und Monitoring
| Status | Aufgabe | Ergebnis |
|---|---|---|
| offen | Immich-Restore-Test implementieren | Restore-Report landet unter `/mnt/user/backups/restore-reports/` |
| in Arbeit (vorbereitet) | Immich-Restore-Test implementieren | `ops/restore-tests/immich-restore-test.sh`, `immich-compose.test.yml` und Dispatcher-Eintrag vorbereitet; lokaler `--what-if` erfolgreich; Abschluss erst nach echtem Host-Lauf mit Report unter `/mnt/user/backups/restore-reports/` |
| offen | Borg-Stale-Alert bauen | Alarm feuert, wenn Borg-Archiv zu alt ist |
| offen | TLS-Cert-Expiry-Alert bauen | Alarm feuert bei Restlaufzeit unter Schwellwert |
| offen | Container-Down-Alert bauen | Unerwartet fehlende Container werden sichtbar |
+81
View File
@@ -0,0 +1,81 @@
# Immich Restore Test
Status: **vorbereitet, noch nicht live ausgefuehrt** (2026-05-26)
Audit-Bezug: `docs/AUDIT_2026-05-25.md` Finding **F-11**
## Zweck
Schliesst die Audit-Luecke aus F-11: Immich ist der groesste Datentopf (Familien-Fotos), und bisher gibt es im Gegensatz zu Vaultwarden, Gitea und Paperless **keinen** verifizierten Mini-Restore-Test. Dieses Dokument verlinkt die Repo-Artefakte und beschreibt den Ablauf aus Operator-Sicht.
## Repo-Artefakte
| Datei | Zweck |
|---|---|
| `ops/restore-tests/immich-compose.test.yml` | isoliertes Test-Compose: pgvecto-rs Postgres + Redis + Immich-Server, ML weggelassen, `127.0.0.1:12283` |
| `ops/restore-tests/immich-restore-test.sh` | Host-Bash-Skript fuer den Lauf, mit `--what-if` und `--keep-data` Flags |
| `ops/restore-tests/immich-restore-test.ps1` | Plan-Scaffold fuer Windows-Operator-Sicht (kein Live-Run) |
| `ops/restore-tests/immich-plan.md` | Fachlicher Plan: Quellen, Schutzregeln, Smoke-Test-Kriterien, bekannte Risiken |
| `ops/restore-tests/immich-runbook.md` | Konkreter Operator-Ablauf, Fehlerfaelle, Schedule-Vorschlag |
## Was der Test abdeckt
- Extraktion von `local/borg-dumps/latest/immich.dump` aus dem aktuellsten Borg-Archiv
- Import in eine isolierte `tensorchord/pgvecto-rs:pg14-v0.2.0` Postgres-Instanz mit demselben Digest wie Produktion
- Start eines isolierten Immich-Server-Containers mit demselben Digest wie Produktion, **ohne** ML-Container und **ohne** Traefik
- Smoke-Test: Login-Seite erreichbar, `assets`- und `users`-Tabelle lesbar
- Markdown-Report unter `/mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md`
- Bereinigung von Test-Container und Restore-Lab-Daten nach Erfolg
## Was der Test bewusst NICHT abdeckt
- Wiederherstellung produktiver Foto-Dateien (`/mnt/user/photos/immich`, `/mnt/user/photos/family_archive`). Diese Pfade werden vom Test nicht angefasst und nicht in den Test-Container gemountet.
- Machine-Learning-Container. Spart Image-Pull-Zeit und RAM; ML-Features sind im Smoke-Test irrelevant.
- Echte Login-Flow per API. Smoke-Test prueft nur, dass Login-Seite ausgeliefert wird.
- Asset-Rendering / Thumbnail-Generierung. Ohne Foto-Files erwartet.
- Produktive Domain `immich.kaleschke.info`. Test laeuft ausschliesslich auf `127.0.0.1:12283`.
## Restore-Stufe
Der Test deckt **Stufe 4 (kritische Anwendungen)** aus `docs/DISASTER_RECOVERY.md` Phase 4 fuer Immich ab, allerdings nur DB-Ebene und UI-Smoke. Voll-Restore inklusive Foto-Dateien aus Borg ist eigener Folgeschritt; das Skript bereitet die Restore-Lab-Struktur dafuer vor.
## Vor dem ersten echten Lauf
| Pruefung | Verantwortlich | Wo |
|---|---|---|
| Dump-Groesse von `immich.dump` bestimmen | Operator | `ls -lh /mnt/user/backups/borg/dumps/latest/immich.dump` |
| Freier Platz unter `/mnt/user/backups/restore-lab/` | Operator | `df -h /mnt/user/backups` |
| Borg-UI-Container laeuft | Operator | `docker ps | grep borg-ui` |
| Trockenlauf mit `--what-if` | Operator | `bash ops/restore-tests/immich-restore-test.sh --what-if` |
| Erster echter Lauf mit `--keep-data` zur Zeitmessung | Operator | `bash ops/restore-tests/immich-restore-test.sh --keep-data` |
## Nach dem ersten erfolgreichen Lauf
1. Report unter `/mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md` ueberpruefen.
2. `docs/RESTORE_MATRIX.md` um den Mini-Restore-Beleg ergaenzen (Datum + Reportpfad), analog zu Paperless 2026-05-07.
3. `ops/restore-tests/schedule.md` von "Immich spaeter" auf konkreten Quartals-Cron umstellen.
4. `docs/AUDIT_2026-05-25_TODO.md` F-11 von "offen" auf "erledigt" stellen.
5. `docs/MIGRATION_LOG.md` mit Mini-Lauf-Befund ergaenzen, ohne Secret-Werte.
## Schutzregeln
- Skript greift ausschliesslich auf den Restore-Lab-Pfad und den Borg-Extract-Cache zu.
- Produktive Pfade unter `/mnt/user/photos/*` und `/mnt/user/appdata/immich_postgres/` werden nicht angefasst.
- Produktive Container `immich_server`, `immich_postgres`, `immich_redis`, `immich_machine_learning` werden nicht gestoppt, nicht beruehrt.
- Borg-Passphrase wird aus `/mnt/user/appdata/secrets/borg_repo_passphrase.txt` gelesen und nicht in Reports, Logs oder Doku geschrieben.
- Test-Container publishen nur auf `127.0.0.1:12283`, nicht auf LAN- oder Tailscale-Interface.
- Keine Traefik-Labels, keine Public-URL fuer Testcontainer.
## Risiken (aus `ops/restore-tests/immich-plan.md`)
- Dump-Groesse und `pg_restore`-Dauer sind aktuell nicht gemessen.
- pgvecto-rs Extension-Mismatch bei Image-Drift moeglich; Compose pinnt denselben Digest wie Produktion.
- Immich-Server-Migrations koennen Startup nach Restore verzoegern; Skript pollt 120 s.
- Bei Schema-Drift (z. B. nach Major-Update) brechen einzelne DB-Queries; das Skript faengt das tolerant ab und schreibt `n/a` in den Report.
## Naechste Operator-Schritte
1. Skript mit `--what-if` ausfuehren und den Plan-Output gegenpruefen.
2. Dump-Groesse und freien Platz pruefen.
3. Ersten echten Lauf mit `--keep-data` ausfuehren, Dauer messen.
4. Bei Erfolg: Restore-Matrix, Schedule, Audit-TODO und Migration-Log nachziehen.
5. Bei Fehler: Restore-Lab nicht selbst manuell bereinigen, sondern den Trap-Cleanup laufen lassen und ggf. Logs sichern, bevor erneut gestartet wird.
+7
View File
@@ -17,6 +17,13 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab
## Historische Meilensteine
### 2026-05-26 - Immich Restore-Smoke-Test vorbereitet (F-11)
- `docs/IMMICH_RESTORE_TEST.md` und `ops/restore-tests/immich-plan.md`/`immich-runbook.md` beschreiben den geplanten Immich-Mini-Restore: `immich.dump` aus Borg, isolierter pgvecto-rs-Test-Postgres, Test-Redis, Immich-Server ohne ML, lokaler Port `127.0.0.1:12283`, keine produktiven Foto-Mounts.
- `ops/restore-tests/immich-restore-test.sh`, `immich-restore-test.ps1` und `immich-compose.test.yml` wurden vorbereitet; der Dispatcher kennt `immich --what-if`.
- Lokal verifiziert: Bash-Syntax, `run-restore-checks.sh immich --what-if`, PowerShell-Dispatcher `-Mode immich -WhatIf`, Docker-Compose-Render und Policy-Check. Kein echter Host-Restore, kein Borg-Extract, kein Produktiv-Container-Eingriff.
- F-11 bleibt fachlich offen bis zum ersten Host-Lauf mit Report unter `/mnt/user/backups/restore-reports/immich-YYYY-MM-DD.md`.
### 2026-05-26 - Audit F-16 und F-20 abgeschlossen (Doku-only)
- F-16: `infra/redis`-Etikett auf die Realitaet abgeglichen. `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md`, `HOMELAB_ARCHITECTURE_MASTER_V2.md` Sektion 13 und `docs/DISASTER_RECOVERY.md` Bootstrap-Stufe 2 beschreiben Redis jetzt als "primaer Paperless-Redis (App-Cache); historisch als shared angelegt, faktisch nur von Paperless genutzt". Immich, Nextcloud, Mealie eigene Redis-Instanzen; Authelia bewusst ohne Redis. Keine Compose-Aenderung.
+1 -1
View File
@@ -46,7 +46,7 @@ Sie ist die fachliche Ergaenzung zu `docs/DISASTER_RECOVERY.md`.
|---|---|---|---|---|---|---|
| Paperless-ngx | Borg + Dumps | `/mnt/user/appdata/paperless-ngx/data`, `/mnt/user/documents/paperless`, `/mnt/user/documents/paperless/export`, `/mnt/user/documents/scans_inbox` | `postgresql17-paperless.dump` | `PAPERLESS_DBPASS`, `PAPERLESS_REDIS`, `borg_repo_passphrase.txt` fuer Restore-Tests | PostgreSQL 17, Redis, Traefik | Web-UI startet, Dokumente vorhanden; Mini-Restore nach `/mnt/user/backups/restore-lab/paperless` am 2026-05-07 erfolgreich validiert |
| Mealie | Borg + Dump | `/mnt/user/appdata/mealie/data`, optional `/mnt/user/appdata/mealie/postgres` bei lokalem Share-Weiterbetrieb | `mealie.dump` | `mealie_postgres_password.txt` | `mealie-postgres`, Traefik | UI startet, Rezepte vorhanden |
| Immich | Borg + Dump | `/mnt/user/photos/immich`, `/mnt/user/photos/family_archive` | `immich.dump` | `IMMICH_DB_PASSWORD`, `immich_postgres_password.txt` | `immich_postgres`, `immich_redis`, Traefik | UI startet, Medienbibliothek sichtbar |
| Immich | Borg + Dump | `/mnt/user/photos/immich`, `/mnt/user/photos/family_archive` | `immich.dump` | `IMMICH_DB_PASSWORD`, `immich_postgres_password.txt` | `immich_postgres`, `immich_redis`, Traefik | UI startet, Medienbibliothek sichtbar; Restore-Smoke-Test-Artefakte vorbereitet (`docs/IMMICH_RESTORE_TEST.md`), erster Host-Report noch offen |
| Mail-Archiver | Borg + Shared Dump | `/mnt/user/appdata/mailarchiver/data-protection-keys` | `postgresql17-mailarchiver.dump` | `MAILARCHIVER_DB_CONNECTION`, `MAILARCHIVER_AUTH_PASSWORD` | PostgreSQL 17, Traefik, Authelia | Authelia-Weiterleitung greift; nach Login startet die Web-UI und das Archiv laesst sich oeffnen |
| Nextcloud | Borg + Dump | `/mnt/user/appdata/nextcloud/html`, `/mnt/user/documents/nextcloud-data` | `nextcloud.dump` | `nextcloud_admin_user.txt`, `nextcloud_admin_password.txt`, `nextcloud_postgres_password.txt` | `nextcloud-postgres`, `nextcloud-redis`, Traefik | Web-UI startet, Login funktioniert, Dateien sichtbar |
| Glance | Git / Borg-Repo | Repo-Konfiguration unter `ops/glance/config/glance.yml`; keine kritische Datenpersistenz | keine | `GLANCE_IMMICH_API_KEY`, `GLANCE_ADGUARD_USERNAME`, `GLANCE_ADGUARD_PASSWORD`, `GLANCE_SPEEDTEST_API_KEY` | Traefik, Authelia, optional interne API-Ziele | Dashboard startet, Widgets laden, Docker-Status laeuft nur ueber `glance-docker-socket-proxy` |