Add validated Paperless restore test pattern
This commit is contained in:
@@ -393,7 +393,7 @@ Wenn weder externer Mirror noch lokaler Clone verfuegbar sind, ist `services/git
|
|||||||
- Unraid-USB-/Flash-Backup pruefen
|
- Unraid-USB-/Flash-Backup pruefen
|
||||||
- Borg-Passphrase extern sicher hinterlegen
|
- Borg-Passphrase extern sicher hinterlegen
|
||||||
- Komodo Stack-ENV-Werte zentral ausserhalb von Komodo dokumentieren
|
- Komodo Stack-ENV-Werte zentral ausserhalb von Komodo dokumentieren
|
||||||
- Restore-Smoke-Test fuer mindestens einen weiteren kritischen Dienst nach Vaultwarden und Gitea dokumentieren
|
- regelmaessige automatisierte Restore-Smoke-Tests fuer Vaultwarden, Gitea und Paperless etablieren
|
||||||
- `komodo-mongo`-Dump nach Major-Upgrades gezielt kontrollieren
|
- `komodo-mongo`-Dump nach Major-Upgrades gezielt kontrollieren
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab
|
|||||||
- Report wurde unter `/mnt/user/backups/restore-reports/gitea-2026-05-07.md` geschrieben.
|
- Report wurde unter `/mnt/user/backups/restore-reports/gitea-2026-05-07.md` geschrieben.
|
||||||
- Testdaten unter `/mnt/user/backups/restore-lab/gitea/data` wurden nach erfolgreichem Lauf wieder bereinigt.
|
- Testdaten unter `/mnt/user/backups/restore-lab/gitea/data` wurden nach erfolgreichem Lauf wieder bereinigt.
|
||||||
|
|
||||||
|
### 2026-05-07 - Paperless Restore-Test praktisch verifiziert
|
||||||
|
|
||||||
|
- Erster echter Paperless-Mini-Restore gegen das produktive Borg-Repo `hetzner_borg_appdata_critical` erfolgreich durchgefuehrt.
|
||||||
|
- Restore umfasste sowohl die Dateipfade als auch `postgresql17-paperless.dump` aus dem Borg-Archiv.
|
||||||
|
- Testinstanzen `restoretest-paperless`, `restoretest-paperless-postgres` und `restoretest-paperless-redis` liefen isoliert ohne Traefik.
|
||||||
|
- Login-Seite war lokal auf `127.0.0.1:18120` erreichbar.
|
||||||
|
- Der Dump-Import in Test-Postgres war erfolgreich; die Test-Datenbank enthielt `25` Dokumente.
|
||||||
|
- Report wurde unter `/mnt/user/backups/restore-reports/paperless-2026-05-07.md` geschrieben.
|
||||||
|
- Testdaten unter `/mnt/user/backups/restore-lab/paperless` wurden nach erfolgreichem Lauf wieder bereinigt.
|
||||||
|
|
||||||
### 2026-05-06 - Komodo Webhook Secret getrennt
|
### 2026-05-06 - Komodo Webhook Secret getrennt
|
||||||
|
|
||||||
- `KOMODO_WEBHOOK_SECRET` von `KOMODO_SECRET_KEY` getrennt und als eigene Stack-ENV-Variable dokumentiert.
|
- `KOMODO_WEBHOOK_SECRET` von `KOMODO_SECRET_KEY` getrennt und als eigene Stack-ENV-Variable dokumentiert.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Sie ist die fachliche Ergaenzung zu `docs/DISASTER_RECOVERY.md`.
|
|||||||
|
|
||||||
| Dienst | Fuehrende Quelle | Datei-Restore | Dump / DB | Secrets / ENV | Abhaengigkeiten | Smoke-Test |
|
| Dienst | Fuehrende Quelle | Datei-Restore | Dump / DB | Secrets / ENV | Abhaengigkeiten | Smoke-Test |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| 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` | PostgreSQL 17, Redis, Traefik | Web-UI startet, Dokumente vorhanden |
|
| 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 |
|
| 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 |
|
||||||
| 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 |
|
| 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 |
|
||||||
@@ -110,8 +110,9 @@ Die Dump-Erzeugung ist host-seitig ueber `ops/borg-ui/scripts/pre-backup-dumps.s
|
|||||||
|
|
||||||
Wenn weitere Restore-Uebungen dokumentiert werden sollen, sind diese Dienste besonders geeignet:
|
Wenn weitere Restore-Uebungen dokumentiert werden sollen, sind diese Dienste besonders geeignet:
|
||||||
|
|
||||||
1. `paperless-ngx`
|
1. `mail-archiver`
|
||||||
2. `gitea`
|
2. `paperless-ngx`
|
||||||
3. `vaultwarden`
|
3. `gitea`
|
||||||
|
4. `vaultwarden`
|
||||||
|
|
||||||
Sie liefern hohen Erkenntnisgewinn ohne den kompletten Homelab-Neuaufbau zu brauchen.
|
Sie liefern hohen Erkenntnisgewinn ohne den kompletten Homelab-Neuaufbau zu brauchen.
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ Ziel:
|
|||||||
- `gitea-restore-test.ps1`: Gitea-Mini-Restore-Ablauf
|
- `gitea-restore-test.ps1`: Gitea-Mini-Restore-Ablauf
|
||||||
- `gitea-plan.md`: konkreter Gitea-Testplan
|
- `gitea-plan.md`: konkreter Gitea-Testplan
|
||||||
- `gitea-compose.test.yml`: isolierte Testinstanz fuer Gitea
|
- `gitea-compose.test.yml`: isolierte Testinstanz fuer Gitea
|
||||||
- spaeter weiterer Test fuer `paperless`
|
- `paperless-restore-test.ps1`: Paperless-Mini-Restore-Ablauf
|
||||||
|
- `paperless-plan.md`: konkreter Paperless-Testplan
|
||||||
|
- `paperless-compose.test.yml`: isolierte Testinstanz fuer Paperless inkl. Test-Postgres und Test-Redis
|
||||||
|
|
||||||
## Automatisierungsmodell
|
## Automatisierungsmodell
|
||||||
|
|
||||||
@@ -50,14 +52,17 @@ Stand nach dem ersten echten Vaultwarden-Test:
|
|||||||
|
|
||||||
Das ist das bevorzugte Muster fuer weitere dateibasierte Restore-Tests wie `gitea`.
|
Das ist das bevorzugte Muster fuer weitere dateibasierte Restore-Tests wie `gitea`.
|
||||||
|
|
||||||
|
Fuer datenbankgestuetzte Dienste wie `paperless` kommt zusaetzlich ein isolierter Dump-Restore in Test-Postgres dazu.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Aktuell ist das erste validierte Muster vorhanden.
|
Aktuell ist das erste validierte Muster vorhanden.
|
||||||
|
|
||||||
- echter Vaultwarden-Restore am 2026-05-07 erfolgreich verifiziert
|
- echter Vaultwarden-Restore am 2026-05-07 erfolgreich verifiziert
|
||||||
- echter Gitea-Restore am 2026-05-07 erfolgreich verifiziert
|
- echter Gitea-Restore am 2026-05-07 erfolgreich verifiziert
|
||||||
|
- echter Paperless-Restore am 2026-05-07 erfolgreich verifiziert
|
||||||
- Restore-Lab und Report-Pfade auf dem Host angelegt
|
- Restore-Lab und Report-Pfade auf dem Host angelegt
|
||||||
- V1-Ablauf weiter ohne `ntfy`, mit Bereinigung nach Erfolg
|
- V1-Ablauf weiter ohne `ntfy`, mit Bereinigung nach Erfolg
|
||||||
- `paperless` ist der naechste Referenz-Restore
|
- naechster grosser Kandidat ist ein weiterer datenbankgestuetzter Dienst oder die Automatisierung
|
||||||
|
|
||||||
Vor dem ersten echten Testlauf muessen Zielpfade, Quellpfade und Bereinigungsschritte bewusst freigegeben werden.
|
Vor dem ersten echten Testlauf muessen Zielpfade, Quellpfade und Bereinigungsschritte bewusst freigegeben werden.
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
services:
|
||||||
|
restoretest-paperless-postgres:
|
||||||
|
image: postgres:17.9@sha256:5b96f1a16bd9768b060dd2ffe55cb6225c4d9ef4d214a8b21eb08134869a97e4
|
||||||
|
container_name: restoretest-paperless-postgres
|
||||||
|
restart: "no"
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Berlin
|
||||||
|
POSTGRES_USER: paperless
|
||||||
|
POSTGRES_DB: paperless
|
||||||
|
POSTGRES_PASSWORD: restoretest-paperless-db
|
||||||
|
PGDATA: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- /mnt/user/backups/restore-lab/paperless/postgres:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U paperless -d paperless"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
restoretest-paperless-redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: restoretest-paperless-redis
|
||||||
|
restart: "no"
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- exec redis-server --appendonly yes --requirepass "restoretest-paperless-redis"
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
restoretest-paperless:
|
||||||
|
image: ghcr.io/paperless-ngx/paperless-ngx:2.20.10@sha256:07a0b4ba01ce377c82a0636e16c0c3d931fde5b7e9304de6601986cc42d9b6e6
|
||||||
|
container_name: restoretest-paperless
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
restoretest-paperless-postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
restoretest-paperless-redis:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
PAPERLESS_TIKA_ENABLED: "0"
|
||||||
|
PAPERLESS_DBENGINE: postgresql
|
||||||
|
PAPERLESS_DBHOST: restoretest-paperless-postgres
|
||||||
|
PAPERLESS_DBNAME: paperless
|
||||||
|
PAPERLESS_DBUSER: paperless
|
||||||
|
PAPERLESS_DBPASS: restoretest-paperless-db
|
||||||
|
PAPERLESS_REDIS: redis://:restoretest-paperless-redis@restoretest-paperless-redis:6379
|
||||||
|
PAPERLESS_TIME_ZONE: Europe/Berlin
|
||||||
|
PAPERLESS_OCR_LANGUAGE: deu+eng
|
||||||
|
PAPERLESS_URL: http://127.0.0.1:18120
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:18120:8000"
|
||||||
|
volumes:
|
||||||
|
- /mnt/user/backups/restore-lab/paperless/consume:/usr/src/paperless/consume
|
||||||
|
- /mnt/user/backups/restore-lab/paperless/data:/usr/src/paperless/data
|
||||||
|
- /mnt/user/backups/restore-lab/paperless/export:/usr/src/paperless/export
|
||||||
|
- /mnt/user/backups/restore-lab/paperless/media:/usr/src/paperless/media
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# Paperless Restore Test Plan
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
Nachweisen, dass ein Paperless-Backup in einer isolierten Testumgebung wieder startbar ist und sowohl Dokumentenpfade als auch PostgreSQL-Dump sauber zusammenlaufen.
|
||||||
|
|
||||||
|
## Quelle
|
||||||
|
|
||||||
|
- Backup-Quelle: Borg / Share-Backup
|
||||||
|
- fachlich relevante Dateipfade:
|
||||||
|
- `/mnt/user/appdata/paperless-ngx/data`
|
||||||
|
- `/mnt/user/documents/paperless`
|
||||||
|
- `/mnt/user/documents/paperless/export`
|
||||||
|
- `/mnt/user/documents/scans_inbox`
|
||||||
|
- fachlich relevanter Dump:
|
||||||
|
- `/mnt/user/backups/borg/dumps/latest/postgresql17-paperless.dump`
|
||||||
|
|
||||||
|
## Test-Ziel
|
||||||
|
|
||||||
|
- Restore-Lab: `/mnt/user/backups/restore-lab/paperless`
|
||||||
|
- Testdatenpfade:
|
||||||
|
- `/mnt/user/backups/restore-lab/paperless/data`
|
||||||
|
- `/mnt/user/backups/restore-lab/paperless/media`
|
||||||
|
- `/mnt/user/backups/restore-lab/paperless/export`
|
||||||
|
- `/mnt/user/backups/restore-lab/paperless/consume`
|
||||||
|
- `/mnt/user/backups/restore-lab/paperless/postgres`
|
||||||
|
- Testcontainer:
|
||||||
|
- `restoretest-paperless`
|
||||||
|
- `restoretest-paperless-postgres`
|
||||||
|
- `restoretest-paperless-redis`
|
||||||
|
- Testport Web: `127.0.0.1:18120:8000`
|
||||||
|
- Report-Ziel: `/mnt/user/backups/restore-reports/paperless-YYYY-MM-DD.md`
|
||||||
|
|
||||||
|
## Schutzregeln
|
||||||
|
|
||||||
|
- produktive Pfade nie beschreiben
|
||||||
|
- produktive Domain `paperless.kaleschke.info` nicht fuer die Testinstanz uebernehmen
|
||||||
|
- keine Traefik-Labels fuer die Testinstanz
|
||||||
|
- keine produktive PostgreSQL- oder Redis-Instanz fuer den Test verwenden
|
||||||
|
- Testcontainer nur gegen Restore-Lab-Daten und isolierte Test-Backends starten
|
||||||
|
|
||||||
|
## Geplanter Ablauf
|
||||||
|
|
||||||
|
1. Restore-Ziel unter `/mnt/user/backups/restore-lab/paperless` vorbereiten
|
||||||
|
2. Paperless-Dateipfade aus Borg in das Restore-Lab wiederherstellen
|
||||||
|
3. Test-Postgres und Test-Redis mit `ops/restore-tests/paperless-compose.test.yml` starten
|
||||||
|
4. `postgresql17-paperless.dump` in Test-Postgres importieren
|
||||||
|
5. Testinstanz `restoretest-paperless` starten
|
||||||
|
6. lokalen Smoke-Test gegen `http://127.0.0.1:18120` ausfuehren
|
||||||
|
7. Report unter `/mnt/user/backups/restore-reports/` schreiben
|
||||||
|
8. Testcontainer stoppen und Testumgebung bereinigen
|
||||||
|
|
||||||
|
## Smoke-Test
|
||||||
|
|
||||||
|
Minimal erfolgreich:
|
||||||
|
|
||||||
|
- Test-Postgres startet
|
||||||
|
- Dump-Import gelingt
|
||||||
|
- Paperless-Web-UI antwortet
|
||||||
|
- mindestens ein Dokument liegt im Restore-Lab-Medienpfad
|
||||||
|
|
||||||
|
Optional spaeter:
|
||||||
|
|
||||||
|
- Login-Seite gezielt pruefen
|
||||||
|
- Dokumentanzahl aus UI oder DB querpruefen
|
||||||
|
- OCR-/Task-Worker-Status verifizieren
|
||||||
|
|
||||||
|
## Noch offen vor dem ersten echten Lauf
|
||||||
|
|
||||||
|
- exakter Borg-Restore-Befehl fuer alle vier Dateipfade
|
||||||
|
- exakter `pg_restore`-Befehl im Test-Postgres
|
||||||
|
- wie stark wir `consume` im ersten Lauf ueberhaupt brauchen
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
param(
|
||||||
|
[string]$BackupSource = "/mnt/user/backups/borg",
|
||||||
|
[string]$DumpSource = "/mnt/user/backups/borg/dumps/latest/postgresql17-paperless.dump",
|
||||||
|
[string]$RestoreRoot = "/mnt/user/backups/restore-lab/paperless",
|
||||||
|
[string]$ReportRoot = "/mnt/user/backups/restore-reports",
|
||||||
|
[string]$BorgPassphraseFile = "/mnt/user/appdata/secrets/borg_repo_passphrase.txt",
|
||||||
|
[switch]$WhatIf
|
||||||
|
)
|
||||||
|
|
||||||
|
$Mode = if ($WhatIf) { "WhatIf" } else { "PlanOnly" }
|
||||||
|
|
||||||
|
Write-Output "Paperless restore test scaffold"
|
||||||
|
Write-Output "BackupSource: $BackupSource"
|
||||||
|
Write-Output "DumpSource: $DumpSource"
|
||||||
|
Write-Output "RestoreRoot: $RestoreRoot"
|
||||||
|
Write-Output "ReportRoot: $ReportRoot"
|
||||||
|
Write-Output "BorgPassphraseFile: $BorgPassphraseFile"
|
||||||
|
Write-Output "Expected Borg source paths inside archive:"
|
||||||
|
Write-Output " - local/appdata/paperless-ngx/data"
|
||||||
|
Write-Output " - local/paperless/media"
|
||||||
|
Write-Output " - local/paperless/export"
|
||||||
|
Write-Output " - local/paperless/consume"
|
||||||
|
Write-Output "Mode: $Mode"
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "Planned steps:"
|
||||||
|
Write-Output "1. Prepare restore-lab target under /mnt/user/backups/restore-lab/paperless"
|
||||||
|
Write-Output "2. Restore Paperless file data into isolated test paths"
|
||||||
|
Write-Output ' Template: borg extract "$BORG_REPO" "::ARCHIVE_NAME" local/appdata/paperless-ngx/data local/paperless/media local/paperless/export local/paperless/consume'
|
||||||
|
Write-Output ' Passphrase source: $(cat /mnt/user/appdata/secrets/borg_repo_passphrase.txt)'
|
||||||
|
Write-Output "3. Start isolated test Postgres and test Redis"
|
||||||
|
Write-Output "4. Import /mnt/user/backups/borg/dumps/latest/postgresql17-paperless.dump into test Postgres"
|
||||||
|
Write-Output "5. Start restoretest-paperless against restored files and isolated DB/Redis"
|
||||||
|
Write-Output "6. Run smoke checks against the local web endpoint"
|
||||||
|
Write-Output "7. Write markdown report under /mnt/user/backups/restore-reports"
|
||||||
|
Write-Output "8. Stop test containers and clean restore data after success"
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "This script is intentionally a scaffold only."
|
||||||
|
Write-Output "No restore, no dump import, no container start, no file write is executed yet."
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# Paperless Restore Runbook
|
||||||
|
|
||||||
|
## Vorbedingungen
|
||||||
|
|
||||||
|
- Borg-Quelle ist verfuegbar
|
||||||
|
- Borg-Passphrase-Datei vorhanden: `/mnt/user/appdata/secrets/borg_repo_passphrase.txt`
|
||||||
|
- aktueller Dump vorhanden: `/mnt/user/backups/borg/dumps/latest/postgresql17-paperless.dump`
|
||||||
|
- Testpfade unter `/mnt/user/backups/restore-lab/` und `/mnt/user/backups/restore-reports/` sind freigegeben
|
||||||
|
|
||||||
|
## Bestaetigter Host-Stand
|
||||||
|
|
||||||
|
- produktive Paperless-Daten liegen unter `/mnt/user/appdata/paperless-ngx/data`
|
||||||
|
- produktive Medien liegen unter `/mnt/user/documents/paperless`
|
||||||
|
- produktiver Exportpfad liegt unter `/mnt/user/documents/paperless/export`
|
||||||
|
- produktiver Consume-Pfad liegt unter `/mnt/user/documents/scans_inbox`
|
||||||
|
- aktueller Dump `postgresql17-paperless.dump` ist vorhanden
|
||||||
|
|
||||||
|
## Bestaetigter Teststand
|
||||||
|
|
||||||
|
- echter Mini-Restore am `2026-05-07` erfolgreich gelaufen
|
||||||
|
- Datei-Restore und Dump kamen aus dem produktiven Borg-Archiv
|
||||||
|
- Testcontainer:
|
||||||
|
- `restoretest-paperless`
|
||||||
|
- `restoretest-paperless-postgres`
|
||||||
|
- `restoretest-paperless-redis`
|
||||||
|
- Login-Seite war lokal auf `127.0.0.1:18120` erreichbar
|
||||||
|
- Dump-Import in Test-Postgres war erfolgreich
|
||||||
|
- Test-Datenbank enthielt `25` Dokumente
|
||||||
|
- Report liegt unter `/mnt/user/backups/restore-reports/paperless-2026-05-07.md`
|
||||||
|
|
||||||
|
## Platzhalter
|
||||||
|
|
||||||
|
- `ARCHIVE_NAME`: Borg-Archiv fuer den Restore-Test
|
||||||
|
- `REPORT_DATE`: z. B. `2026-05-07`
|
||||||
|
- `BORG_REPO`: Host-Borg-Repo
|
||||||
|
- `BORG_PASSPHRASE_FILE`: `/mnt/user/appdata/secrets/borg_repo_passphrase.txt`
|
||||||
|
|
||||||
|
## Ablauf
|
||||||
|
|
||||||
|
1. Testpfade vorbereiten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/user/backups/restore-lab/paperless/{data,media,export,consume,postgres}
|
||||||
|
mkdir -p /mnt/user/backups/restore-reports
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless/data/*
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless/media/*
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless/export/*
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless/consume/*
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless/postgres/*
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Paperless-Dateipfade aus Borg in das Restore-Lab extrahieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export BORG_REPO='...'
|
||||||
|
export BORG_PASSPHRASE="$(cat /mnt/user/appdata/secrets/borg_repo_passphrase.txt)"
|
||||||
|
borg list "$BORG_REPO"
|
||||||
|
cd /mnt/user/backups/restore-lab/paperless
|
||||||
|
borg extract "$BORG_REPO" "::ARCHIVE_NAME" local/appdata/paperless-ngx/data local/paperless/media local/paperless/export local/paperless/consume
|
||||||
|
mv /mnt/user/backups/restore-lab/paperless/local/appdata/paperless-ngx/data /mnt/user/backups/restore-lab/paperless/data
|
||||||
|
mv /mnt/user/backups/restore-lab/paperless/local/paperless/media /mnt/user/backups/restore-lab/paperless/media
|
||||||
|
mv /mnt/user/backups/restore-lab/paperless/local/paperless/export /mnt/user/backups/restore-lab/paperless/export
|
||||||
|
mv /mnt/user/backups/restore-lab/paperless/local/paperless/consume /mnt/user/backups/restore-lab/paperless/consume
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Test-Postgres und Test-Redis starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f /mnt/user/services/homelab/ops/restore-tests/paperless-compose.test.yml up -d restoretest-paperless-postgres restoretest-paperless-redis
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Dump in Test-Postgres importieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -i restoretest-paperless-postgres pg_restore -U paperless -d paperless < /mnt/user/backups/borg/dumps/latest/postgresql17-paperless.dump
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Testinstanz starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f /mnt/user/services/homelab/ops/restore-tests/paperless-compose.test.yml up -d restoretest-paperless
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Smoke-Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -I http://127.0.0.1:18120
|
||||||
|
docker logs restoretest-paperless --tail 50
|
||||||
|
find /mnt/user/backups/restore-lab/paperless/media -type f | head -n 10
|
||||||
|
```
|
||||||
|
|
||||||
|
Minimal erfolgreich:
|
||||||
|
|
||||||
|
- Dump-Import gelingt
|
||||||
|
- HTTP-Antwort kommt
|
||||||
|
- Dokumentenpfad ist im Restore-Lab befuellt
|
||||||
|
|
||||||
|
7. Testcontainer wieder stoppen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f /mnt/user/services/homelab/ops/restore-tests/paperless-compose.test.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
8. Testdaten nach erfolgreichem Lauf bereinigen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf /mnt/user/backups/restore-lab/paperless
|
||||||
|
```
|
||||||
|
|
||||||
|
## Festgelegte Entscheidungen
|
||||||
|
|
||||||
|
- Paperless nutzt fuer Restore-Tests immer isoliertes Test-Postgres und Test-Redis.
|
||||||
|
- Testdaten werden nach erfolgreichem Lauf geloescht.
|
||||||
|
- `ntfy` wird nicht im ersten echten Lauf eingebunden.
|
||||||
|
- Die Borg-Passphrase wird fuer Restore-Tests aus einer Host-Secret-Datei gelesen, nicht aus Borg-UI-Interna.
|
||||||
Reference in New Issue
Block a user