9edd6c24e6
Reine Doku-Fixes nach DR-Tabletop 2026-06-03 und Operator-Antworten auf vier offene Fragen. DISASTER_RECOVERY.md: - Abschnitt 3 Voraussetzungen: Operator-DR-Workstation als Pflichtposten - Phase 0: privater GitHub-Mirror, Read-PAT/Deploy-Key, expliziter Repo- Bootstrap-Pfad Workstation -> Unraid - Abschnitt 6.1: homelab_smtp_password.txt, n8n_encryption_key.txt, monitoring/influxdb/filebrowser Secrets nachgezogen - Neuer Abschnitt 7.3: Borg-Extract ohne borg-ui (DR-Workstation oder docker run borgbackup/borg), Passphrase-Eingabe interaktiv - Phase 4 neue Stufe 0 "Docker-Grundlage": docker network create frontend_net/backend_net/monitoring_net + dynamic/ Pre-Check - Phase 4 Stufe 1: LE-Staging-Hinweis bei verlorenem acme.json - Phase 4 Stufe 3 "Wichtige Stolperfallen": KOMODO_*-Quelle, Mongo- Datadir/Secret-Mismatch, extra_hosts-IP, Stack-ENV-Wiederherstellung - Phase 5.3: App-DB-Verifikation per docker logs EXTERNAL_DEPENDENCIES.md: - GitHub-Mirror als privat klargestellt + Read-PAT/Deploy-Key Pflicht - Operator-DR-Workstation als kritische Abhaengigkeit - KOMODO_*-Notiz und GitHub-Read-PAT als noch nicht angelegt erfasst - Hetzner-Maintenance-Key offline bestaetigt (Operator-Antwort 2026-06-03) - Neuer Abschnitt "DR-Workstation Bare-Metal-Kit" mit konkretem Inhalt AUDIT_2026-05-25_TODO.md: - Vier neue P1-Operator-Aufgaben: KOMODO_*-Notiz, Read-PAT, DR-Workstation- Setup, Nextcloud-Restore-Test scharf laufen lassen DR_DRILL_2026-06-03.md: - Folge-Iteration-Tabelle: welcher Finding wo adressiert wurde Operator-Aufgaben (nicht delegierbar) sind als P1 markiert. Nichts in Runtime/Compose beruehrt, kein Container gestartet.
549 lines
24 KiB
Markdown
549 lines
24 KiB
Markdown
# 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
|
|
- `docs/RESTORE_HANDBOOK.md` - praktische Restore-Betriebsanleitung
|
|
- `docs/SERVICES_RECOVERY.md` - Recovery-kritische `/mnt/user/services`-Pfade, Gitea-Mirror und Komodo-Bootstrap
|
|
- `docs/EXTERNAL_DEPENDENCIES.md` - externe Provider/Konten und Ausfall-Szenarien
|
|
- `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 | privater GitHub-Push-Mirror `michaelkaleschke-spec/homelab-infra` und lokaler aktueller Clone vorhanden; fuer Bare-Metal-DR zusaetzlich Read-Only-PAT/Deploy-Key offline im DR-Kit |
|
|
| Operator-DR-Workstation | Gaming-PC mit aktuellem Repo-Clone, WSL2 + Borg-Client, SSH-Key fuer Hetzner Storage Box, Offline-Kopie Borg-Passphrase; Bestandteile siehe `docs/EXTERNAL_DEPENDENCIES.md` Abschnitt "DR-Workstation Bare-Metal-Kit" |
|
|
| Unraid USB-/Flash-Backup | `unraid-flash-config.tar.gz` wird vor Borg unter `/mnt/user/backups/borg/dumps/latest` erzeugt und nach Hetzner/Borg gesichert; Unraid-Connect-Cloud-Backup optional zusaetzlich |
|
|
| Borg-Ziel | nicht nur lokal auf demselben Ausfallpfad |
|
|
| Borg-Passphrase | Host-Secret-Datei vorhanden und fuer Borg-Zugriff verifiziert; externe Offline-Hinterlegung vom Operator am 2026-05-26 bestaetigt |
|
|
| Secrets-Dateien | ueber Borg bzw. Restore-Quellen abgedeckt |
|
|
| Komodo Stack ENV-Werte | extern dokumentiert, z. B. Vaultwarden |
|
|
| Services-Recovery | `docs/SERVICES_RECOVERY.md` gepflegt, insbesondere Gitea-Repo-Mirror und Komodo-Bootstrap |
|
|
| Hardware-/Netzwerkdaten | `docs/HARDWARE_INVENTORY.md` und `docs/NETWORK_INVENTORY.md` mit echten Werten gefuellt |
|
|
| 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.
|
|
|
|
Verfuegbare Wege:
|
|
|
|
- externer Push-Mirror: `https://github.com/michaelkaleschke-spec/homelab-infra` (privat, Read-PAT/Deploy-Key noetig — siehe `docs/EXTERNAL_DEPENDENCIES.md` Abschnitt "DR-Workstation Bare-Metal-Kit")
|
|
- lokaler Bare-Clone auf der Operator-DR-Workstation (Standardweg)
|
|
- normaler lokaler Arbeits-Clone auf der Operator-DR-Workstation
|
|
|
|
Operativer Pfad fuer den Repo auf den frisch installierten Unraid-Host:
|
|
|
|
1. Operator-DR-Workstation holt den aktuellen Clone (lokaler Stand oder per `git clone` aus dem GitHub-Mirror mit dem offline gesicherten Read-PAT/Deploy-Key).
|
|
2. Kopie via USB, SMB oder `rsync ueber SSH/Tailscale` nach `/mnt/user/services/homelab-infra/` auf dem Unraid-Host.
|
|
3. Stand pruefen: `git -C /mnt/user/services/homelab-infra log --oneline -1` zeigt einen plausibel aktuellen Commit.
|
|
|
|
Wenn **weder GitHub-Mirror noch lokaler Repo-Clone** verfuegbar sind, 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
|
|
|
|
Primaere lokale/off-site Restore-Quelle fuer die bestehende Flash-Konfiguration ist das Borg-Artefakt `unraid-flash-config.tar.gz` aus `/mnt/user/backups/borg/dumps/latest`. Dieses Archiv enthaelt `/boot/config` und muss wie Secret-Material behandelt werden.
|
|
|
|
### 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_smtp_password.txt`
|
|
- `authelia_storage_encryption_key.txt`
|
|
- `immich_postgres_password.txt`
|
|
- `komodo_mongo_password.txt`
|
|
- `mealie_postgres_password.txt`
|
|
- `nextcloud_admin_password.txt`
|
|
- `nextcloud_admin_user.txt`
|
|
- `nextcloud_postgres_password.txt`
|
|
- `postgres_password.txt`
|
|
- `redis_password.txt`
|
|
- `borg_repo_passphrase.txt`
|
|
- `vaultwarden_admin_token.txt`
|
|
- `homelab_smtp_password.txt`
|
|
- `n8n_encryption_key.txt`
|
|
- `monitoring_grafana_admin_password.txt`
|
|
- `monitoring_grafana_influxdb_token.txt`
|
|
- `influxdb3_admin_token.json`
|
|
- `filebrowser_admin_password.txt`
|
|
- `hermes_runner_id_ed25519`
|
|
|
|
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`
|
|
- `HERMES_DASHBOARD_HOST`
|
|
- Hermes Host-`.env` fuer Provider-/API-/Home-Assistant-Tokens
|
|
- `KOMODO_SECRET_KEY`
|
|
- `KOMODO_WEBHOOK_SECRET`
|
|
- `KOMODO_JWT_SECRET`
|
|
- `KOMODO_MONGO_PASSWORD`
|
|
- `KOMODO_PERIPHERY_PASSKEY`
|
|
- `APP_KEY` und `ADMIN_PASSWORD` fuer `speedtest-tracker`
|
|
|
|
Zusaetzlich rebuildbar (keine kritische Recovery-Quelle, koennen aus Provider-/App-UIs neu erzeugt werden):
|
|
|
|
- `GLANCE_IMMICH_API_KEY`, `GLANCE_ADGUARD_USERNAME`, `GLANCE_ADGUARD_PASSWORD`, `GLANCE_SPEEDTEST_API_KEY` fuer `glance` Community-/Live-Widgets
|
|
|
|
### 6.2.1 Restore-Quellen fuer Stack-ENV-Werte
|
|
|
|
Stack-ENV-Werte liegen **nicht im Repo** und **nicht als Datei-Secret** unter `/mnt/user/appdata/secrets/`. Sie sind nur an drei Stellen erreichbar; bei Recovery in dieser Reihenfolge pruefen:
|
|
|
|
1. **Komodo-Mongo-Dump** `komodo-mongo.archive.gz` unter `/mnt/user/backups/borg/dumps/latest/`. Solange Komodo selbst noch nicht laeuft, ist der Mongo-Dump die kanonische Quelle. Restore in eine Test-Mongo-Instanz, anschliessend Werte aus der `stack`-Collection lesen. **Niemals** Werte in andere Dokumente kopieren.
|
|
2. **Vaultwarden** Eintrag "Komodo Stack ENV / KalliLab CORE" (bzw. der entsprechende Eintrag pro Stack). Voraussetzung: Vaultwarden ist bereits restauriert (`docs/RESTORE_MATRIX.md`).
|
|
3. **Externe Operator-Notiz** (versiegelter Umschlag, Bankschliessfach, oder analoge Sicherung neben der Borg-Passphrase). Nur als Notfall-Quelle, wenn weder Komodo-Mongo noch Vaultwarden verfuegbar sind.
|
|
|
|
**Reihenfolge-Konsequenz fuer den Bootstrap-Pfad in Phase 4 (Stufe 4 weiter unten):**
|
|
|
|
- Vor dem Start von `apps/paperless/`, `apps/immich/`, `apps/mail-archiver/` und `ops/speedtest/` muessen die jeweiligen Stack-ENV-Werte in Komodo wieder hinterlegt sein.
|
|
- Wenn `komodo-mongo.archive.gz` frisch ist, koennen die Werte beim Komodo-Restart aus dem Dump zurueckgespielt werden, ohne dass jemand sie sieht.
|
|
- Wenn Vaultwarden vor Komodo restauriert wird (was hier nicht der Standardweg ist), kann auch von dort gelesen werden.
|
|
|
|
**Paperless ist die wichtigste bewusste Ausnahme:** `PAPERLESS_DBPASS` und `PAPERLESS_REDIS` sind seit der Hardening-Phase bewusst Stack-ENV (Paperless unterstuetzt `_FILE` fuer DB-Pass nicht). Ein Komodo-Mongo-Dump-Verlust ist daher fuer Paperless gleichbedeutend mit Re-Initialisierung der App-DB; in diesem Fall hilft nur ein Restore aus Vaultwarden oder externer Notiz.
|
|
|
|
**Regel:** Konkrete Werte werden **nirgendwo** im Repo, in Logs, in Doku-Kommentaren oder in ntfy-Meldungen wiedergegeben. Auch dieses Dokument haelt nur Variablennamen, Quellen und Reihenfolge fest, keine Werte.
|
|
|
|
### 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/homelab-infra`
|
|
- `/mnt/user/services/stacks`
|
|
- `/mnt/user/services/posture-check`
|
|
- Details zu `/mnt/user/services/` und Komodo/Gitea-Bootstrap stehen in `docs/SERVICES_RECOVERY.md`
|
|
- `/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`
|
|
- `/mnt/user/backups/borg/dumps/latest/unraid-flash-config.tar.gz`
|
|
- dienstspezifische App- und Nutzdatenpfade
|
|
|
|
**Nicht blind alles extrahieren**, wenn nur einzelne Pfade oder Dienste betroffen sind.
|
|
|
|
### 7.3 Borg-Extract ohne `borg-ui`-Container
|
|
|
|
Im Bare-Metal-Fall ist `borg-ui` selbst kalt. Der initiale Borg-Extract laeuft deshalb nicht ueber den Container, sondern wahlweise ueber:
|
|
|
|
1. **Operator-DR-Workstation** (Standardweg) - WSL2 + `borgbackup` extrahieren gezielt nach `/mnt/user/backups/restore-lab/...` oder per `rsync`/SMB auf den Unraid-Host.
|
|
2. **Native Docker-Variante auf Unraid** - `docker run --rm -e BORG_PASSPHRASE=... -v /mnt/user/backups/restore-lab:/restore -v ~/.ssh:/root/.ssh:ro borgbackup/borg:1.4 ...`.
|
|
|
|
Erst nach Stufe 5 Phase 4 ist `borg-ui` produktiv und uebernimmt den weiteren Betrieb. Die Borg-Passphrase wird interaktiv aus der Offline-Sicherung eingegeben, nicht in Skripte/Tickets kopiert.
|
|
|
|
---
|
|
|
|
## 8. Phase 4 - Bootstrap-Reihenfolge der Stacks
|
|
|
|
**Nie alle Stacks gleichzeitig starten.**
|
|
|
|
### Stufe 0 - Docker-Grundlage
|
|
|
|
Vor dem ersten `docker compose up` muss sichergestellt sein:
|
|
|
|
1. `docker info` antwortet ohne Fehler.
|
|
2. Externe Docker-Netze existieren. Wenn nicht vorhanden:
|
|
|
|
```bash
|
|
docker network create --driver bridge frontend_net
|
|
docker network create --driver bridge --internal backend_net
|
|
docker network create --driver bridge monitoring_net
|
|
```
|
|
|
|
3. Pfad `/mnt/user/appdata/traefik/dynamic/` enthaelt `middlewares.yml`, `tls.yml`, `dashboards.yml` (Sonderregel siehe Sektion 10). Ohne diese Dateien startet Traefik ohne Middleware-Definitionen und alle Authelia-geschuetzten Routen brechen still.
|
|
|
|
Erfolgskriterium: `docker network ls` zeigt `frontend_net`, `backend_net`, `monitoring_net`; Traefik-`dynamic/`-Dateien sind vorhanden und valide.
|
|
|
|
### Stufe 1 - Netz und Zugang
|
|
|
|
1. `traefik/`
|
|
2. `host-services/Adguard/`
|
|
3. `host-services/tailscale/`
|
|
|
|
**LE-Rate-Limit-Vorsicht:** Wenn `/mnt/user/appdata/traefik/letsencrypt/acme.json` verloren oder unklar ist, zuerst gegen Let's Encrypt Staging ausstellen lassen (`--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory`). Erst nach gruenem Smoke wieder auf Production-CA. Hintergrund: 50 Zertifikate pro Domain pro Woche reicht bei einem hektischen Wiederanlauf nicht, wenn man die Sub-Domains mehrfach hochzieht.
|
|
|
|
Ziel:
|
|
|
|
- Web-Einstieg funktioniert
|
|
- DNS/Resolver-Basis ist da
|
|
- Remote-Zugang ist wieder verfuegbar
|
|
|
|
### Stufe 2 - Gemeinsame Backends und Identity
|
|
|
|
4. `infra/postgresql17/` (PostgreSQL 18 runtime, historischer Stack-Name bleibt fuer Service-DNS stabil)
|
|
5. `security/authelia/`
|
|
6. `infra/redis/`
|
|
7. `core/gitea/`
|
|
|
|
Ziel:
|
|
|
|
- gemeinsame DB verfuegbar
|
|
- zentrale Auth laeuft; Authelia nutzt bewusst kein Redis-Session-Backend
|
|
- Authelia SMTP-Notifier kann GMX erreichen
|
|
- Redis verfuegbar als App-Cache fuer Paperless (`infra/redis` ist historisch als "shared" angelegt, wird faktisch nur von Paperless genutzt)
|
|
- Git-Zugriff wiederhergestellt
|
|
|
|
### Stufe 3 - Deploy-System
|
|
|
|
8. `ops/komodo/` - **Kaltstart-Anker, kein Auto-Deploy**
|
|
|
|
Komodo wird in dieser Stufe bewusst **nicht** ueber Gitea-Webhook deployed. Der vollstaendige Bootstrap-Pfad ist in `docs/SERVICES_RECOVERY.md` Abschnitt "Komodo Bootstrap" als lineare Stufen A-F dokumentiert. Hier in der DR-Reihenfolge gilt der Einstiegspunkt:
|
|
|
|
- Recovery-Anker ist `ops/komodo/docker-compose.yml` aus dem Repo (lokaler Clone, GitHub-Mirror oder `homelab-infra.bundle`-Restore).
|
|
- Komodo-Stack-ENV-Werte (`KOMODO_*`) sind Stack-ENV-only und werden aus Vaultwarden oder externer Notiz wiederhergestellt (siehe `docs/SECRETS_MAP.md` Abschnitt "Stack-ENV-only Secrets - Restore-Wege").
|
|
- Erst nach erfolgreicher Validierung der Komodo-Web-UI und Periphery-Verbindung werden in den naechsten Stufen die produktiven Stacks aufgenommen.
|
|
|
|
Ziel:
|
|
|
|
- Komodo Core und Mongo laufen
|
|
- Periphery verbindet sich wieder
|
|
- Stacks koennen wieder aus Git konsumiert werden
|
|
|
|
**Wichtige Stolperfallen in Stufe 3:**
|
|
|
|
- **KOMODO_*-Werte sind nicht aus dem eigenen Mongo-Dump rekonstruierbar.** Pflichtquelle im Bare-Metal: offline gesicherte Operator-Notiz (Status 2026-06-03: noch nicht angelegt, siehe `docs/EXTERNAL_DEPENDENCIES.md` und Audit-Restliste). Vaultwarden ist erst in Stufe 4 verfuegbar.
|
|
- **Mongo-Datadir und `komodo_mongo_password.txt` muessen aus demselben Snapshot stammen.** Bei Mismatch akzeptiert Mongo den Login nicht und der Stack startet nicht. Auswege: entweder die zur Datadir passende Secret-Datei aus dem gleichen Borg-Stand restaurieren, oder Datadir leeren, neu initialisieren und Daten via `mongorestore --archive --gzip` aus `komodo-mongo.archive.gz` einspielen (Drill belegt 2026-06-03).
|
|
- **`extra_hosts: git.kaleschke.info:192.168.178.58`** in `ops/komodo/docker-compose.yml` ist hardgecodet. Bei geaenderter Host-LAN-IP auf der Recovery-Hardware den Wert vor `compose up` anpassen, sonst kann Komodo-Core das interne Gitea nicht erreichen.
|
|
- **Stack-ENV-Werte fuer Apps in Stufe 4** (Paperless/Immich/Mailarchiver/Speedtest) sind in Stufe 3 noch leer. Zwei Wege: (a) optionaler `mongorestore` aus `komodo-mongo.archive.gz` direkt nach Komodo-Start, dann sind alle Stack-ENVs zurueck; (b) Werte manuell in der Komodo-UI eintragen, sobald Vaultwarden in Stufe 4 verfuegbar ist (was Paperless/Immich/Mailarchiver hinter Vaultwarden zwingt, nicht parallel).
|
|
|
|
### Stufe 4 - Kritische Anwendungen
|
|
|
|
9. `security/vaultwarden/`
|
|
10. `apps/paperless/`
|
|
11. `apps/immich/`
|
|
12. `apps/mealie/`
|
|
13. `apps/mail-archiver/`
|
|
14. `apps/nextcloud/`
|
|
|
|
### Stufe 5 - Restliche Apps und Ops
|
|
|
|
15. `apps/ntfy/`
|
|
16. `apps/paperless-gpt/`
|
|
17. `apps/bentopdf/`
|
|
18. `ops/glance/`
|
|
19. `ops/borg-ui/`
|
|
20. `ops/filebrowser/`
|
|
21. `ops/glances/`
|
|
22. `ops/scrutiny/`
|
|
23. `ops/speedtest/`
|
|
24. `monitoring/`
|
|
25. `ops/hermes-agent/`
|
|
26. `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
|
|
- Nextcloud startet und sieht Dateien
|
|
- Pro App: `docker logs <container>` zeigt keine `password authentication failed`-, `FATAL: role does not exist`- oder `Connection refused`-Eintraege (verifiziert, dass Stack-ENV-Werte und DB-Rollen passen)
|
|
|
|
### 9.4 Backup-/Beobachtungsebene
|
|
|
|
- Borg UI startet und kennt sein Repo noch
|
|
- aktuelle Dump-Artefakte sind vorhanden
|
|
- Glance / Monitoring / ntfy sind wieder da
|
|
- Hermes Gateway und Dashboard starten; `hermes.kaleschke.info` leitet anonym zu Authelia weiter
|
|
|
|
---
|
|
|
|
## 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.
|
|
|
|
### `authelia`
|
|
|
|
Authelia nutzt GMX SMTP fuer Identity-/2FA-Benachrichtigungen.
|
|
|
|
Vor dem Start muessen vorhanden sein:
|
|
|
|
- `/mnt/user/appdata/secrets/authelia_smtp_password.txt`
|
|
- SMTP-Zugang fuer `michideheld@gmx.de`
|
|
|
|
Beim Smoke-Test muss `authelia config validate` erfolgreich sein; der SMTP-Startup-Check darf den Start nicht blockieren.
|
|
|
|
### `nextcloud`
|
|
|
|
`nextcloud` ist bewusst kein AIO-Stack, sondern ein klassischer App-/PostgreSQL-/Redis-Stack.
|
|
|
|
Vor dem Start muessen vorhanden sein:
|
|
|
|
- `/mnt/user/appdata/secrets/nextcloud_admin_user.txt`
|
|
- `/mnt/user/appdata/secrets/nextcloud_admin_password.txt`
|
|
- `/mnt/user/appdata/secrets/nextcloud_postgres_password.txt`
|
|
|
|
Zusaetzlich muss der Nutzdatenpfad `/mnt/user/documents/nextcloud-data` erreichbar sein.
|
|
|
|
Beim PostgreSQL-Restore beachten:
|
|
|
|
- vor einem produktiven Dump `occ maintenance:mode --on` setzen
|
|
- die produktive DB-Rolle kann von `POSTGRES_USER` abweichen; aktuell nutzt Nextcloud laut `config.php` die Rolle `oc_admin`
|
|
- nach Restore und erfolgreichem `occ status` den Wartungsmodus mit `occ maintenance:mode --off` beenden
|
|
|
|
### 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`
|
|
- Unraid-Flash-Artefakt: `unraid-flash-config.tar.gz` plus `.sha256` und Manifest im selben Zielpfad
|
|
|
|
### Redis 8 Restore / Rollback
|
|
|
|
Redis-Instanzen laufen auf der 8.x-Schiene. Vor Major-Upgrades wird `redis-cli SAVE` ausgefuehrt und der jeweilige Datenpfad kopiert.
|
|
|
|
Aktive Pfade und Besonderheiten:
|
|
|
|
- Shared Redis: `/mnt/user/appdata/redis`, Passwort aus `redis_password.txt`, AOF aktiv.
|
|
- Nextcloud Redis: `/mnt/user/appdata/nextcloud/redis`, ohne Redis-Passwort, Snapshot-Persistenz.
|
|
- Immich Redis: cache/queue-only ohne bind-mounted Datenpfad; Restore-Wahrheit ist Immich Postgres + Foto-Dateien, nicht Redis.
|
|
|
|
Rollback:
|
|
|
|
1. Abhaengige App stoppen.
|
|
2. Redis stoppen.
|
|
3. Compose auf das vorherige Redis-7.4-Image zuruecksetzen.
|
|
4. Bei Shared/Nextcloud den vor dem Cutover kopierten Datenpfad zurueckkopieren.
|
|
5. Redis und App starten, `redis-cli INFO server` und App-Smoke pruefen.
|
|
|
|
### PostgreSQL 18 Major-Upgrade / Rollback
|
|
|
|
Produktive PostgreSQL-18-Cluster verwenden das Docker-Image-Layout mit Host-Mount auf `/var/lib/postgresql` und `PGDATA=/var/lib/postgresql/18/docker`.
|
|
|
|
Aktive Datenpfade:
|
|
|
|
- Shared PostgreSQL: `/mnt/user/appdata/postgresql18`
|
|
- Mealie PostgreSQL: `/mnt/user/appdata/mealie/postgres18`
|
|
- Nextcloud PostgreSQL: `/mnt/user/appdata/nextcloud/postgres18`
|
|
|
|
Rollback-Altstaende wurden nach Burn-in am 2026-06-02 reversibel archiviert:
|
|
|
|
- Shared PostgreSQL 17: `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/postgresql17`
|
|
- Mealie PostgreSQL 17: `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/mealie-postgres17`
|
|
- Nextcloud PostgreSQL 17: `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/nextcloud-postgres17`
|
|
|
|
Restore-Reihenfolge fuer den Shared-Cluster:
|
|
|
|
1. Frischen PostgreSQL-18-Cluster starten.
|
|
2. Globals aus `pg_dumpall --globals-only` einspielen.
|
|
3. Den bekannten Bootstrap-Konflikt fuer `CREATE ROLE mailarchiver;` gezielt tolerieren bzw. herausfiltern, danach `ALTER ROLE mailarchiver ...` dennoch einspielen.
|
|
4. Datenbanken anlegen und Custom-Format-Dumps mit `pg_restore` einspielen.
|
|
5. Restore-Logs auf echte `ERROR`, `FATAL` und `PANIC` pruefen.
|
|
|
|
Immich ist bewusst nicht Teil dieses PostgreSQL-18-Laufs: Die produktive DB bleibt auf PostgreSQL 14 und nutzt das Immich-Postgres-Image mit VectorChord/pgvector. VectorChord-Backups brauchen zum Restore ein Image mit VectorChord; der alte pgvecto.rs-Datenpfad ist als Rollback-Altstand unter `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/immich-postgres-pgvecto-rs` archiviert.
|
|
|
|
### Hermes Agent
|
|
|
|
Hermes nutzt einen lokalen Build und hostseitige Runtime-Daten.
|
|
|
|
Vor dem Start muessen vorhanden sein:
|
|
|
|
- `/mnt/user/appdata/hermes-agent/data`
|
|
- `/mnt/user/appdata/hermes-agent/ssh`
|
|
- `/mnt/user/appdata/secrets/hermes_runner_id_ed25519`
|
|
- die hostseitige Hermes `.env` mit Provider-/API-/Home-Assistant-Tokens
|
|
|
|
Smoke-Test: `hermes-gateway` healthcheck ist gruen, `hermes.kaleschke.info` leitet fuer anonyme Requests zu Authelia weiter.
|
|
|
|
### Gitea
|
|
|
|
`Micha/homelab-infra` wird als privater GitHub-Push-Mirror gespiegelt. Dieser Mirror ist der bevorzugte Repo-Bootstrap, falls Gitea selbst nach einem Ausfall noch nicht laeuft. Wenn weder GitHub-Mirror noch lokaler Clone verfuegbar sind, ist `services/gitea/data` selbst Teil des kritischen Wiederanlaufs.
|
|
|
|
---
|
|
|
|
## 11. Offene Vorbereitungs-To-dos
|
|
|
|
- Unraid-USB-/Flash-Backup regelmaessig ueber `unraid-flash-config.tar.gz` und optional Unraid Connect pruefen
|
|
- Borg-Passphrase ist laut Operator-Bestaetigung vom 2026-05-26 extern/offline hinterlegt; bei Reviews nur Existenz/Lesbarkeit der Offline-Kopie pruefen, nie den Wert dokumentieren
|
|
- Komodo Stack-ENV-Werte zentral ausserhalb von Komodo dokumentieren
|
|
- regelmaessige automatisierte Restore-Smoke-Tests fuer Vaultwarden, Gitea und Paperless etablieren
|
|
- `komodo-mongo`-Dump nach Major-Upgrades gezielt kontrollieren
|
|
|
|
---
|
|
|
|
## 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.
|