129 lines
6.2 KiB
Markdown
129 lines
6.2 KiB
Markdown
# 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 `ops/restore-tests/schedule.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 `ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23`
|
|
- 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
|
|
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)
|
|
|
|
```bash
|
|
# 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
|
|
- VectorChord-/pgvector-Extensions sind in der 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:
|
|
|
|
```bash
|
|
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 asset;"
|
|
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 ... vector/vchord` | Test-Postgres-Image passt nicht zur Produktion | 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.
|