docs(dr): tabletop-folge - DR.md + EXTERNAL_DEPENDENCIES haerten
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.
This commit is contained in:
@@ -62,7 +62,8 @@ 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 |
|
||||
| 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 |
|
||||
@@ -87,9 +88,15 @@ Deshalb gilt:
|
||||
|
||||
Verfuegbare Wege:
|
||||
|
||||
- externer Push-Mirror: `https://github.com/michaelkaleschke-spec/homelab-infra`
|
||||
- lokaler Bare-Clone auf dem PC
|
||||
- normaler lokaler Arbeits-Clone auf dem PC
|
||||
- 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.
|
||||
|
||||
@@ -148,6 +155,12 @@ Erwartete Basis unter `/mnt/user/appdata/secrets/`:
|
||||
- `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:
|
||||
@@ -241,18 +254,46 @@ Besonders kritisch:
|
||||
|
||||
**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
|
||||
@@ -290,6 +331,13 @@ Ziel:
|
||||
- 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/`
|
||||
@@ -342,6 +390,7 @@ Ziel:
|
||||
- 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user