diff --git a/README.md b/README.md index 8f6af75..0664aaa 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ Vor jeder Aenderung lesen: 1. `HOMELAB_ARCHITECTURE_MASTER_V2.md` 2. `docs/WORKFLOW.md` +Bei Restore-, Host-Ausfall- oder Wiederanlauf-Fragen zusaetzlich: + +3. `docs/DISASTER_RECOVERY.md` +4. `docs/RESTORE_MATRIX.md` + ## Architektur - Host: Unraid @@ -57,4 +62,5 @@ Vor jeder Aenderung lesen: - Homepage ist das aktive produktive Frontend / Start-Dashboard. - Traefik `dynamic/` bleibt eine dokumentierte manuelle Host-Sync-Ausnahme ausserhalb des normalen Komodo-Deployments. - Mutable Image-Tags sind auf die aktuell laufenden Digests eingefroren; echte Versions-Upgrades erfolgen bewusst separat. +- Disaster-Recovery und dienstspezifische Restore-Quellen sind in `docs/DISASTER_RECOVERY.md` und `docs/RESTORE_MATRIX.md` beschrieben. - Der verbindliche Detailablauf steht in `docs/WORKFLOW.md`. diff --git a/docs/DISASTER_RECOVERY.md b/docs/DISASTER_RECOVERY.md new file mode 100644 index 0000000..86f3341 --- /dev/null +++ b/docs/DISASTER_RECOVERY.md @@ -0,0 +1,359 @@ +# Disaster Recovery - KalliLab CORE + +Dieses Dokument beschreibt den **kontrollierten Wiederanlauf nach einem Totalausfall des Unraid-Hosts**. + +Es ist bewusst **repo-genau** fuer dieses Homelab geschrieben und ersetzt keine Backup-Dokumentation im engeren Sinn. + +Verwandte Dokumente: + +- `docs/ROLLBACK.md` - Rueckweg bei Fehlern im laufenden GitOps-Betrieb +- `docs/RESTORE_MATRIX.md` - Restore-Quellen und Verifikationsregeln pro Dienst +- `ops/borg-ui/BACKUP_SCOPE.md` - Zielbild des Borg-Scopes + +--- + +## 1. Ziel und Geltungsbereich + +Dieses Runbook behandelt primaer den Fall: + +- Unraid-Host war ausgefallen oder musste neu aufgesetzt werden +- Array / Shares sind wieder verfuegbar +- Daten auf den Festplatten sind grundsaetzlich noch lesbar oder koennen aus Borg wiederhergestellt werden + +Es behandelt **nicht** im Detail: + +- den Rueckweg einzelner Fehl-Deployments im laufenden Betrieb +- eine spontane Live-Reparatur an einem einzelnen Service +- einen kompletten Datenverlust ohne verfuegbares Borg- oder Share-Material + +--- + +## 2. Zwei verschiedene Ernstfaelle + +Diese beiden Szenarien muessen sauber getrennt werden: + +### A. Host-/Systemausfall, aber Daten auf den Shares sind noch da + +Das ist der wahrscheinlichere und einfachere Fall. + +Dann muessen in vielen Bereichen **keine Daten aus Borg extrahiert** werden. Es reicht oft: + +1. Unraid sauber neu aufzusetzen +2. Shares wieder einzubinden +3. Repo / Secrets / Laufzeitpfade zu pruefen +4. Stacks in der richtigen Reihenfolge wieder hochzufahren + +### B. Daten muessen wirklich aus Borg wiederhergestellt werden + +Das ist der schwerere Fall. + +Dann muessen gezielt die in `docs/RESTORE_MATRIX.md` beschriebenen Pfade, Dumps und Secrets aus Borg oder anderen Restore-Quellen zurueckgeholt werden. + +**Merksatz:** Erst klaeren, ob wir nur den Host wiederbeleben oder echte Nutz-/App-Daten aus Backups zurueckholen muessen. + +--- + +## 3. Voraussetzungen vor einem Ernstfall + +Diese Punkte sollten **vor** einem echten Ausfall geklaert sein: + +| Thema | Sollzustand | +|---|---| +| Repo-Zugang ausserhalb von Gitea | externer Mirror oder lokaler aktueller Clone vorhanden | +| Unraid USB-/Flash-Backup | eingerichtet und wiederherstellbar | +| Borg-Ziel | nicht nur lokal auf demselben Ausfallpfad | +| Borg-Passphrase | extern sicher hinterlegt | +| Secrets-Dateien | ueber Borg bzw. Restore-Quellen abgedeckt | +| Komodo Stack ENV-Werte | extern dokumentiert, z. B. Vaultwarden | +| Restore-Smoke-Tests | fuer mindestens 1-2 kritische Dienste nachgewiesen | + +**Wichtig:** Dieses Dokument ist nur so gut wie die Vorbereitung ausserhalb des Repos. + +--- + +## 4. Phase 0 - Repo-Zugang sicherstellen + +Nach einem Totalausfall kann es sein, dass `gitea` selbst noch nicht laeuft. + +Deshalb gilt: + +1. Wenn moeglich, Repo ueber einen externen Mirror oder einen lokalen aktuellen Clone holen. +2. Nur wenn `gitea` bereits wieder verfuegbar ist, direkt aus `git.kaleschke.info` klonen. + +Empfohlene Wege: + +- externer Push-Mirror +- lokaler Bare-Clone auf dem PC +- normaler lokaler Arbeits-Clone auf dem PC + +Wenn **kein externer Repo-Zugang** besteht, ist `services/gitea/data` selbst ein kritischer Restore-Pfad. + +--- + +## 5. Phase 1 - Unraid und Shares wiederherstellen + +### 5.1 Unraid-Grundzustand + +1. Unraid USB/Flash wiederherstellen oder neu aufsetzen +2. Lizenz / Device-Zuordnung sauber herstellen +3. Array wieder zuweisen und starten +4. Grundlegende Shares pruefen + +### 5.2 Erwartete Shares / Pfade + +Mindestens diese Pfade muessen wieder verfuegbar sein: + +- `/mnt/user/appdata` +- `/mnt/user/backups` +- `/mnt/user/services` +- `/mnt/user/documents` +- `/mnt/user/photos` + +Je nach Dienst zusaetzlich: + +- `/mnt/user/finance` +- `/mnt/remotes/...` fuer externe Backup-Ziele + +Wenn diese Pfade **nicht** sauber da sind, keine Stacks starten. + +--- + +## 6. Phase 2 - Secrets und kritische Restore-Pfade pruefen + +Bevor produktive Dienste hochfahren, muessen die wichtigsten Secret- und Konfigurationspfade verifiziert werden. + +### 6.1 Zentrale Secrets + +Erwartete Basis unter `/mnt/user/appdata/secrets/`: + +- `authelia_jwt_secret.txt` +- `authelia_postgres_password.txt` +- `authelia_session_secret.txt` +- `authelia_storage_encryption_key.txt` +- `immich_postgres_password.txt` +- `komodo_mongo_password.txt` +- `mealie_postgres_password.txt` +- `postgres_password.txt` +- `redis_password.txt` +- `vaultwarden_admin_token.txt` + +Weitere relevante Secret-Pfade: + +- `/mnt/user/appdata/traefik/secrets/cloudflare_dns_api_token` +- `/mnt/user/appdata/code-server/secrets/password` + +### 6.2 Stack-ENV-Werte ausserhalb von Datei-Secrets + +Diese Werte sind vor dem Start der betroffenen Dienste zu pruefen bzw. wieder in Komodo zu hinterlegen: + +- `PAPERLESS_DBPASS` +- `PAPERLESS_REDIS` +- `IMMICH_DB_PASSWORD` +- `MAILARCHIVER_DB_CONNECTION` +- `MAILARCHIVER_AUTH_PASSWORD` +- `KOMODO_SECRET_KEY` +- `KOMODO_JWT_SECRET` +- `KOMODO_MONGO_PASSWORD` +- `KOMODO_PERIPHERY_PASSKEY` +- relevante `HOMEPAGE_VAR_*` +- `APP_KEY` und `ADMIN_PASSWORD` fuer `speedtest-tracker` + +### 6.3 Rechte + +Nach einem Restore oder manuellem Rueckkopieren: + +- Secret-Dateien wieder auf sinnvolle restriktive Rechte setzen +- keine produktiven Dienste starten, solange offensichtliche Secret-Dateien fehlen + +--- + +## 7. Phase 3 - Was wirklich aus Borg kommen muss + +Nicht alles muss in jedem Fall aus Borg zurueckgespielt werden. + +### 7.1 Typischer Host-Ausfall ohne Datenverlust + +In diesem Fall meist **kein kompletter Borg-Extract** notwendig. + +Stattdessen: + +1. Shares und Pfade pruefen +2. Secrets pruefen +3. Dumps unter `/mnt/user/backups/borg/dumps/latest` pruefen +4. Stacks kontrolliert hochfahren + +### 7.2 Wenn echte Daten aus Borg benoetigt werden + +Dann nur gezielt die in `docs/RESTORE_MATRIX.md` beschriebenen Pfade wiederherstellen. + +Besonders kritisch: + +- `/mnt/user/appdata/secrets` +- `/mnt/user/appdata/traefik` +- `/mnt/user/services/gitea/data` +- `/mnt/user/appdata/authelia/config` +- `/mnt/user/appdata/komodo/core` +- `/mnt/user/appdata/komodo/periphery` +- `/mnt/user/backups/borg/dumps/latest` +- dienstspezifische App- und Nutzdatenpfade + +**Nicht blind alles extrahieren**, wenn nur einzelne Pfade oder Dienste betroffen sind. + +--- + +## 8. Phase 4 - Bootstrap-Reihenfolge der Stacks + +**Nie alle Stacks gleichzeitig starten.** + +### Stufe 1 - Netz und Zugang + +1. `traefik/` +2. `host-services/Adguard/` +3. `host-services/tailscale/` + +Ziel: + +- Web-Einstieg funktioniert +- DNS/Resolver-Basis ist da +- Remote-Zugang ist wieder verfuegbar + +### Stufe 2 - Gemeinsame Backends und Identity + +4. `infra/postgresql17/` +5. `infra/redis/` +6. `security/authelia/` +7. `core/gitea/` + +Ziel: + +- gemeinsame DB / Redis verfuegbar +- zentrale Auth laeuft +- Git-Zugriff wiederhergestellt + +### Stufe 3 - Deploy-System + +8. `ops/komodo/` + +Ziel: + +- Komodo Core und Mongo laufen +- Periphery verbindet sich wieder +- Stacks koennen wieder aus Git konsumiert werden + +### Stufe 4 - Kritische Anwendungen + +9. `security/vaultwarden/` +10. `apps/paperless/` +11. `apps/immich/` +12. `apps/mealie/` +13. `apps/mail-archiver/` + +### Stufe 5 - Restliche Apps und Ops + +14. `apps/homepage/` +15. `apps/ntfy/` +16. `apps/paperless-gpt/` +17. `ops/uptime-kuma/` +18. `ops/borg-ui/` +19. `ops/backrest/` +20. `ops/filebrowser/` +21. `ops/glances/` +22. `ops/scrutiny/` +23. `ops/speedtest/` +24. `infra/ddns-updater/` + +**Regel:** Nach jeder Stufe kurz pruefen, bevor die naechste beginnt. + +--- + +## 9. Phase 5 - Verifikation nach dem Wiederanlauf + +### 9.1 Fundament + +- `traefik.kaleschke.info` erreichbar +- Authelia-Login funktioniert +- AdGuard beantwortet DNS-Anfragen +- Tailscale ist verbunden + +### 9.2 GitOps + +- `git.kaleschke.info` erreichbar +- Repo vorhanden +- `komodo.kaleschke.info` erreichbar +- Periphery verbunden + +### 9.3 Kritische Apps + +- Vaultwarden startet und ist erreichbar +- Paperless startet und sieht Dokumente +- Immich startet und sieht Medien +- Mealie startet +- Mail-Archiver startet + +### 9.4 Backup-/Beobachtungsebene + +- Borg UI startet und kennt sein Repo noch +- aktuelle Dump-Artefakte sind vorhanden +- Uptime Kuma / Homepage / ntfy sind wieder da + +--- + +## 10. Bekannte Sonderregeln + +### Traefik `dynamic/` + +`traefik/dynamic/*` bleibt eine dokumentierte manuelle Ausnahme. + +Das bedeutet: + +- Git allein reicht hier nicht +- die Dateien unter `/mnt/user/appdata/traefik/dynamic/` muessen real vorhanden sein +- nach einem Restore oder Neuaufbau diesen Pfad explizit pruefen + +### `paperless-ngx` + +`paperless-ngx` bleibt bewusst bei Stack Environment Variables fuer: + +- `PAPERLESS_DBPASS` +- `PAPERLESS_REDIS` + +Nach einem Komodo-Neuaufbau muessen diese Werte vor dem Start des Stacks wieder gesetzt sein. + +### Borg-Dumps + +Die Dump-Erzeugung ist host-seitig gedacht, nicht als Borg-UI-Inline-Hook. + +Relevant: + +- Dump-Ziel: `/mnt/user/backups/borg/dumps/latest` +- Skript: `ops/borg-ui/scripts/pre-backup-dumps.sh` + +### Gitea + +Wenn weder externer Mirror noch lokaler Clone verfuegbar sind, ist `services/gitea/data` selbst Teil des kritischen Wiederanlaufs. + +--- + +## 11. Offene Vorbereitungs-To-dos + +- externer Repo-Zugang fuer den Ernstfall absichern +- Unraid-USB-/Flash-Backup pruefen +- Borg-Passphrase extern sicher hinterlegen +- Komodo Stack-ENV-Werte zentral ausserhalb von Komodo dokumentieren +- Restore-Smoke-Test fuer mindestens einen weiteren kritischen Dienst dokumentieren +- `komodo-mongo`-Dump gezielt bestaetigen + +--- + +## 12. Kurzform fuer den Ernstfall + +Wenn es schnell gehen muss: + +1. Unraid und Shares sauber wiederherstellen +2. Repo-Zugang sichern +3. Secrets und Stack-ENV-Werte pruefen +4. Stacks in der festgelegten Reihenfolge hochfahren +5. Kritische Apps testen +6. Nur bei echtem Datenbedarf gezielt aus Borg wiederherstellen + +Dieses Dokument soll **Ruhe in den Ablauf bringen**, nicht Hektik erzeugen. diff --git a/docs/MIGRATION_LOG.md b/docs/MIGRATION_LOG.md index 4a0c51c..509514f 100644 --- a/docs/MIGRATION_LOG.md +++ b/docs/MIGRATION_LOG.md @@ -52,6 +52,7 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab - `speedtest-tracker` von `APP_DEBUG=true` auf `false` umgestellt. - Mutable Image-Tags fuer produktive Stacks auf die aktuell laufenden Digests eingefroren, um Deployments reproduzierbar zu machen. - `paperless-ngx` bleibt fuer `PAPERLESS_DBPASS` und `PAPERLESS_REDIS` vorerst bewusst bei Stack Environment Variables; keine Live-Migration auf `_FILE`, solange der aktuelle Stand stabil laeuft. +- Disaster-Recovery-Runbook und Restore-Matrix fuer den Totalausfall-/Wiederanlauf-Fall neu dokumentiert. --- diff --git a/docs/RESTORE_MATRIX.md b/docs/RESTORE_MATRIX.md new file mode 100644 index 0000000..ad52ff9 --- /dev/null +++ b/docs/RESTORE_MATRIX.md @@ -0,0 +1,103 @@ +# Restore Matrix - KalliLab CORE + +Diese Matrix beschreibt fuer die wichtigsten Dienste: + +- was die fuehrende Restore-Quelle ist +- welche Pfade oder Dumps relevant sind +- welche Secrets gebraucht werden +- wovon der Dienst abhaengt +- wie ein sinnvoller Smoke-Test aussieht + +Sie ist die fachliche Ergaenzung zu `docs/DISASTER_RECOVERY.md`. + +--- + +## Legende + +- **Fuehrende Quelle** = die primaere Restore-Wahrheit fuer diesen Dienst +- **Datei-Restore** = relevante Verzeichnisse / Volume-Pfade +- **Dump / DB** = relevante Dump-Artefakte oder Datenbankabhaengigkeiten +- **Secrets / ENV** = Dinge, die vor dem Start wieder da sein muessen +- **Smoke-Test** = minimaler Nachweis, dass der Restore wirklich greift + +--- + +## Tier 1 - Kritisch fuer Wiederanlauf + +| Dienst | Fuehrende Quelle | Datei-Restore | Dump / DB | Secrets / ENV | Abhaengigkeiten | Smoke-Test | +|---|---|---|---|---|---|---| +| Traefik | Share / Borg | `/mnt/user/appdata/traefik`, besonders `dynamic/`, `letsencrypt`, `secrets` | keine eigene DB | `cloudflare_dns_api_token` | `frontend_net`, `backend_net` | `https://traefik.kaleschke.info` erreichbar, Dashboard ueber Authelia | +| AdGuard Home | Share / Borg | `/mnt/user/appdata/adguard/conf` | keine | keine zusaetzlichen Repo-Secrets dokumentiert | `dns_net`, `frontend_net` | DNS-Aufloesung funktioniert | +| Tailscale | Share / Borg | `/mnt/user/appdata/tailscale` | keine | Tailscale-State im Pfad | Host-Netz | Tailscale verbunden | +| PostgreSQL 17 | Share + Dumps | `/mnt/user/appdata/postgresql17` | `postgresql17-globals.sql`, `postgresql17-mailarchiver.dump`, `postgresql17-paperless.dump`, optional `postgresql17-authelia.dump` | `postgres_password.txt` | `backend_net` | DB startet, Ziel-Datenbanken vorhanden | +| Redis | Share / Host | `/mnt/user/appdata/redis` | keine | `redis_password.txt` | `backend_net` | Redis startet, Apps verbinden sich | +| Authelia | Borg | `/mnt/user/appdata/authelia/config`, `/mnt/user/appdata/secrets/*authelia*` | Shared PostgreSQL, optional Dump `postgresql17-authelia.dump` | JWT/Session/Storage/Postgres-Secret-Dateien | PostgreSQL 17, Redis, Traefik | Login-Seite und ForwardAuth funktionieren | +| Gitea | Borg / Share | `/mnt/user/services/gitea/data` | SQLite in `/data` | keine separaten Secret-Dateien dokumentiert | Traefik | Web-UI erreichbar, Repo sichtbar, SSH-Port reagiert | +| Komodo | Borg / Share | `/mnt/user/appdata/komodo/core`, `/mnt/user/appdata/komodo/periphery` | `komodo-mongo.archive.gz` falls verifiziert | `komodo_mongo_password.txt`, `KOMODO_*` Stack ENV | Traefik, Mongo, Gitea | UI erreichbar, Periphery verbunden | +| Vaultwarden | Borg / Share | `/mnt/user/appdata/vaultwarden` | dateibasiert | `vaultwarden_admin_token.txt` | Traefik | Login-Seite erreichbar, Tresor-Daten sichtbar | + +--- + +## Tier 2 - Wichtige Anwendungen + +| 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 | +| 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 | +| Mail-Archiver | Borg + Shared Dump | `/mnt/user/appdata/mailarchiver/data-protection-keys` | `postgresql17-mailarchiver.dump` | `MAILARCHIVER_DB_CONNECTION`, `MAILARCHIVER_AUTH_PASSWORD` | PostgreSQL 17, Traefik | Web-UI startet, Archiv laesst sich oeffnen | +| Homepage | Borg / Share | `/mnt/user/appdata/homepage` | keine | `HOMEPAGE_VAR_*` | Traefik, Authelia | Dashboard startet, Widgets laden | +| ntfy | Borg / Share | `/mnt/user/appdata/ntfy` | keine | keine besonderen Secret-Dateien dokumentiert | Traefik | UI und Push-Endpunkt erreichbar | +| Paperless-GPT | Borg / Share | `/mnt/user/appdata/paperless-gpt` | keine eigene DB | `PAPERLESS_API_TOKEN` | Traefik, Paperless | UI startet, Konfiguration vorhanden | + +--- + +## Tier 3 - Rebuildbar / Sekundaer + +| Dienst | Fuehrende Quelle | Datei-Restore | Dump / DB | Secrets / ENV | Abhaengigkeiten | Smoke-Test | +|---|---|---|---|---|---|---| +| Borg UI | Borg / Share | `/mnt/user/appdata/borg-ui/data` | keine eigene DB | Borg-Repo-Creds in `/data` | Traefik | UI startet, Repo-Verbindung bekannt | +| Backrest | Share | `/mnt/user/appdata/backrest/*` | keine | SSH-/Repo-Creds im Mount | Traefik | UI startet | +| Uptime Kuma | Share | `/mnt/user/appdata/uptime-kuma` | keine | keine besonderen Secret-Dateien dokumentiert | Traefik, Authelia | Monitore vorhanden | +| Filebrowser | Share | `/mnt/user/appdata/filebrowser` | keine | keine separaten Secret-Dateien dokumentiert | Traefik, Authelia | UI startet | +| Glances | Rebuildbar | kein kritischer Zustand | keine | keine | Traefik, Authelia | UI startet | +| Scrutiny | Teilweise rebuildbar | `/mnt/user/appdata/scrutiny` falls gewuenscht | InfluxDB bewusst nicht Teil des Critical-Scope | keine | Traefik, Authelia | UI startet, Laufwerke sichtbar | +| Speedtest Tracker | Share | `/mnt/user/appdata/speedtest-tracker/config` | SQLite im App-Pfad | `APP_KEY`, `ADMIN_PASSWORD` | Traefik, Authelia | UI startet | +| ddns-updater | Rebuildbar | geringe Persistenzrelevanz | keine | Provider-Zugang ueber Stack ENV | Internetzugang | Update-Job laeuft | + +--- + +## Dumps und Restore-Artefakte + +Aktuell relevante Dump-Artefakte unter `/mnt/user/backups/borg/dumps/latest`: + +- `postgresql17-globals.sql` +- `postgresql17-mailarchiver.dump` +- `postgresql17-paperless.dump` +- `postgresql17-authelia.dump` (optional / wenn vorhanden) +- `mealie.dump` +- `immich.dump` +- `komodo-mongo.archive.gz` (noch gesondert verifizieren) + +Die Dump-Erzeugung ist host-seitig ueber `ops/borg-ui/scripts/pre-backup-dumps.sh` vorgesehen. + +--- + +## Praktische Restore-Regeln + +- Nicht mehrere kritische Dienste gleichzeitig restaurieren. +- Erst die Abhaengigkeiten wiederherstellen, dann die App. +- Bei Unsicherheit zuerst in Testpfade oder Testinstanzen pruefen. +- Der minimale Erfolg ist **nicht** "Container startet", sondern "fachlicher Smoke-Test gelingt". + +--- + +## Erste sinnvolle Referenz-Restores + +Wenn weitere Restore-Uebungen dokumentiert werden sollen, sind diese Dienste besonders geeignet: + +1. `gitea` +2. `paperless-ngx` +3. `vaultwarden` + +Sie liefern hohen Erkenntnisgewinn ohne den kompletten Homelab-Neuaufbau zu brauchen.