Compare commits
6 Commits
52414c47be
...
0723eccca1
| Author | SHA1 | Date | |
|---|---|---|---|
| 0723eccca1 | |||
| 3bfecdd291 | |||
| c4fd4154db | |||
| dddb33d900 | |||
| 8eac93c1a5 | |||
| cfa02ce627 |
@@ -54,7 +54,7 @@ Kontext bewusst gesichert, bevor weitere Live-Aenderungen passieren:
|
||||
| erledigt | `docs/STORAGE_LAYOUT.draft.md` finalisieren | Datei als `docs/STORAGE_LAYOUT.md` Active v1.4 gefuehrt; Draft-Blocker entfernt |
|
||||
| erledigt (Baseline) | Disk- und Share-TBDs eintragen | Disk-Modelle, Seriennummern, Groessen, Filesysteme und Share-Cache-Settings aus `docs/HARDWARE_INVENTORY.md` und Host-Readout 2026-05-27 uebernommen; Retention-/Schwellen-Kalibrierung bleibt Folgeaufgabe |
|
||||
| erledigt (Skript + Host-Test) | Gitea-Repo-Mirror-Mechanik definieren | `ops/borg-ui/scripts/gitea-bundle-mirror.sh` erzeugt verifizierte Bundles unter `/mnt/user/backups/git-bundles/gitea`; Host-Erstlauf 2026-05-26: 4 Bundles, Checksums OK, `homelab-infra.bundle` klonbar und `git fsck` sauber; Schedule bleibt offen |
|
||||
| offen | Komodo-Bootstrap-Pfad beschreiben | Kaltstart ohne laufendes Komodo ist dokumentiert |
|
||||
| erledigt (Doku) | Komodo-Bootstrap-Pfad beschreiben | `docs/SERVICES_RECOVERY.md` enthaelt linearen Bootstrap in Stufen A-F mit Recovery-Anker `ops/komodo/docker-compose.yml`, expliziter Abgrenzung zum Self-Stack, Secret-Reihenfolge und Validierungs-Kommandos; `docs/DISASTER_RECOVERY.md` Stufe 3 verlinkt auf Bootstrap-Pfad. Trockenlauf-Skript bleibt als offene Folgeaufgabe. |
|
||||
| erledigt | Immich-Restore-Test planen | Testumfang, Datenpfade und Smoke-Test-Kriterium sind in `docs/IMMICH_RESTORE_TEST.md`, `ops/restore-tests/immich-plan.md` und `ops/restore-tests/immich-runbook.md` festgehalten; erster Host-Lauf am 2026-05-27 erfolgreich |
|
||||
|
||||
## Sprint 3 - Restore und Monitoring
|
||||
@@ -65,18 +65,18 @@ Kontext bewusst gesichert, bevor weitere Live-Aenderungen passieren:
|
||||
| in Arbeit (Regeln vorbereitet) | Borg-Stale-Alert bauen | Textfile-Metrik `homelab_borg_last_completed_timestamp_seconds` und Prometheus-Regeln vorbereitet; Host-Smoke 2026-05-27 schreibt Metriken, aktueller Borg-Status `completed_with_warnings`; Abschluss nach Host-Schedule + Prometheus-Reload/Testalert |
|
||||
| in Arbeit (Regeln vorbereitet) | TLS-Cert-Expiry-Alert bauen | Blackbox-Regeln fuer 21-/7-Tage-Schwellen vorbereitet; Abschluss nach Prometheus-Reload/Testalert |
|
||||
| in Arbeit (Regeln vorbereitet) | Container-Down-Alert bauen | Textfile-Metrik `homelab_critical_container_running{name=...}` und Alert vorbereitet; Host-Smoke 2026-05-27: alle gelisteten kritischen Container `1`; Abschluss nach Host-Schedule + Prometheus-Reload/Testalert |
|
||||
| offen | Family-View Dashboard definieren | Uptime, Backup-Frische, Cert-Tage, Disk-Fuellung auf einer Seite |
|
||||
| erledigt (Spezifikation) | Family-View Dashboard definieren | `docs/FAMILY_VIEW_DASHBOARD.md` enthaelt Layout, PromQL-Queries, Thresholds und Build-Reihenfolge fuer ein `homelab-family-view`-Dashboard. JSON wird bewusst erst angelegt, sobald Borg-Stale-/Cert-Expiry-/Container-Down-Metriken stabil live sind und ein manueller Build im Grafana-UI das Layout bestaetigt hat. |
|
||||
|
||||
## Sprint 4 - Familien- und Betriebsdoku
|
||||
|
||||
| Status | Aufgabe | Ergebnis |
|
||||
|---|---|---|
|
||||
| in Arbeit | Familien-Onboarding schreiben | Familienverstaendlich (kein Tech-Jargon); deckt Nextcloud, Immich, Vaultwarden, Mealie, Paperless, Plex, Passwort-/2FA-Verlust und WAN-/DNS-Stoerungen ab; finaler Stand vor Wochenend-Einladung |
|
||||
| erledigt (final vor Einladung) | Familien-Onboarding schreiben | `docs/FAMILY_ONBOARDING.md` ist final redigiert: familienverstaendliche Sprache, App-eigene 2FA statt SSO-Versprechen, neuer "Bewusst nicht versprochen"-Block (kein Einheits-Login, kein 24/7-SLA, kein Hotline-Support, keine Datenweitergabe), konkrete Was-tun-Anleitungen. Einladungstermin bleibt Operator-Aufgabe. |
|
||||
| erledigt (Baseline) | Capacity-/Lifecycle-Review erstellen | Cache 6 %, Array/User-Shares 33 %, lokale Backups 2.2G; H:/-Nearline-Bewertung ergaenzt; externe Cold-Storage-Groessen bleiben offen |
|
||||
| erledigt | USV-Test oder USV-Entscheidung | Operator-Entscheidung 2026-05-26: aktuell keine USV-Anschaffung; Power-Loss-Risiko wird bewusst akzeptiert und dokumentiert |
|
||||
| erledigt (Baseline) | H:/ als zusaetzliches lokales Backupziel bewerten | Als zweite Nearline-Kopie und Freeze-Sicherung sinnvoll; kein Offsite-Ersatz, kein CIFS-Hard-Mount am Unraid; Pull-Modell vom Windows-PC ist der getestete Weg (siehe `docs/CAPACITY_AND_LIFECYCLE.md`) |
|
||||
| in Arbeit (vorbereitet) | H:/ Groesse und Pull-Schedule festschreiben | Groesse erfasst: 8.0T NTFS, 3.91T belegt, 4.10T frei, `Healthy`; `docs/H_DRIVE_NEARLINE_PULL.md` und `ops/h-drive-nearline/pull-critical-backups.ps1` vorbereitet; SMB-Quelle erreichbar; empfohlener Schedule taeglich 05:30, Task noch nicht aktiviert |
|
||||
| erledigt (Abweichung dokumentiert) | FRITZ!Box-Portfreigaben gegen Repo-Soll abgleichen | UI am 2026-05-27 geprueft: aktiv sind `80/tcp` und `443/tcp` auf `192.168.178.58`; `222/tcp` fehlt. Korrektur ist ein separater produktiver Router-Schritt nach Operator-Freigabe |
|
||||
| erledigt (Abweichung dokumentiert) | FRITZ!Box-Portfreigaben gegen Repo-Soll abgleichen | UI am 2026-05-27 geprueft: aktiv sind `80/tcp` und `443/tcp` auf `192.168.178.58`; `222/tcp` fehlt; zusaetzlich UPnP-Selbstfreigabe durch `PC-192-168-178-71`. Korrektur ist ein separater produktiver Router-Schritt nach Operator-Freigabe; Vorbereitung in `docs/FRITZBOX_PORT_CORRECTION_PLAN.md` |
|
||||
|
||||
## Sprint 5 - Auth und Frontdoor, bewusst zuletzt
|
||||
|
||||
@@ -103,8 +103,8 @@ In diesem Audit-Zyklus werden diese Punkte **nicht** umgesetzt. Sie sind dokumen
|
||||
|
||||
| Status | Aufgabe | Bemerkung |
|
||||
|---|---|---|
|
||||
| offen | Zweites echtes Off-site (F-03) | H:/ ersetzt das **nicht**; rsync.net / BorgBase EU2 / Cold-Wechselplatte mit fester Rotation pruefen |
|
||||
| offen | Restore-Lab-Drill quartalsweise dokumentieren | Routine festlegen, nicht ad-hoc |
|
||||
| offen (Entscheidungsvorlage) | Zweites echtes Off-site (F-03) | H:/ ersetzt das **nicht**; Optionen rsync.net / BorgBase EU2 / Cold-Wechselplatte in `docs/OFFSITE_BACKUP_OPTIONS.md` gegenuebergestellt, Empfehlung rsync.net oder Cold-Platte; Operator-Entscheidung und Budget-Freigabe stehen aus |
|
||||
| erledigt (Routine dokumentiert) | Restore-Lab-Drill quartalsweise dokumentieren | `docs/RESTORE_DRILL_ROUTINE.md` definiert Drei-Stufen-Modell (Freshness woechentlich / Mini-Restore monatlich-bimonatlich / DR-Sanity quartalsweise), Quartals-Belegung Q1-Q4 mit Dienst-Rotation, Immich 2026-05-27 als bestaetigter Erstlauf gefuehrt, 10-Punkte-Sanity-Check, kein Host-Schedule angelegt. `ops/restore-tests/schedule.md` verweist jetzt auf Drill-Routine. |
|
||||
|
||||
## Offene Host-Werte
|
||||
|
||||
|
||||
@@ -276,7 +276,13 @@ Ziel:
|
||||
|
||||
### Stufe 3 - Deploy-System
|
||||
|
||||
8. `ops/komodo/`
|
||||
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:
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Familien-Willkommen - KalliLab CORE
|
||||
|
||||
Status: Entwurf 2026-05-26. Zielgruppe: Familie. Kein Technik-Wortschatz noetig.
|
||||
Status: **Final-Stand vor Wochenend-Einladung** (2026-05-27). Zielgruppe: Familie. Kein Technik-Wortschatz noetig.
|
||||
|
||||
Diese Seite richtet sich an alle, die zuhause unsere eigenen Apps nutzen wollen. Du brauchst kein Technikwissen. Wenn etwas unklar ist, frag Michi.
|
||||
Diese Seite richtet sich an alle, die zuhause unsere eigenen Apps nutzen. Du brauchst kein Technikwissen. Wenn etwas unklar ist: einfach Michi fragen.
|
||||
|
||||
Wir laden die Familie am Wochenende ein, sobald alles fertig ist. Bis dahin ist diese Seite **Entwurf** — Details koennen sich noch aendern.
|
||||
Du musst nichts auswendig lernen. Wenn du nur eine Sache aus dieser Seite mitnimmst: **Passwoerter gehoeren in Vaultwarden, nicht auf Zettel und nicht in den Browser.**
|
||||
|
||||
---
|
||||
|
||||
@@ -37,7 +37,10 @@ Beim ersten Mal bekommst du von Michi:
|
||||
|
||||
- deinen Benutzernamen (in der Regel dein Vorname klein geschrieben)
|
||||
- ein Start-Passwort, das du beim ersten Login aenderst
|
||||
- bei einigen Apps spaeter zusaetzlich einen **Zweitfaktor** (eine kleine 6-stellige Zahl aus einer App)
|
||||
|
||||
Wenn eine App selbst einen **Zweitfaktor** anbietet (zum Beispiel Nextcloud), bekommst du dafuer am Anfang gemeinsam mit Michi eine kleine Authentifizierungs-App eingerichtet. Das ist eine extra Schicht: zusaetzlich zum Passwort tippst du beim Login eine 6-stellige Zahl aus dieser App ein.
|
||||
|
||||
> Hinweis: Ein **einheitliches 2FA fuer alle Apps gleichzeitig** ist noch nicht eingerichtet. Aktuell hat jede App ihre eigene Anmeldung. Das bleibt erst einmal so. Wenn sich da etwas aendert, sagt Michi rechtzeitig Bescheid.
|
||||
|
||||
**Bitte:**
|
||||
|
||||
@@ -76,8 +79,9 @@ Das ist die App, die deinen Eltern wahrscheinlich am meisten bringt.
|
||||
|
||||
### "Ich habe mein 2FA verloren (neues Handy, App geloescht)."
|
||||
|
||||
- Michi schreiben. Er kann den Zweitfaktor zuruecksetzen, sobald er dich persoenlich identifiziert.
|
||||
- Michi schreiben. Er kann den Zweitfaktor in der betroffenen App fuer dich zuruecksetzen, sobald er dich persoenlich identifiziert.
|
||||
- Wir richten den Zweitfaktor dann neu auf dem neuen Handy ein.
|
||||
- Wenn moeglich: vor einem Handy-Wechsel kurz Bescheid sagen, dann koennen wir 2FA vorher umziehen, statt zuruecksetzen.
|
||||
|
||||
### "Das Handy-Foto-Backup ist stehen geblieben."
|
||||
|
||||
@@ -132,11 +136,22 @@ Michi laesst es dich wissen, wenn ein Wartungsfenster geplant ist.
|
||||
|
||||
## Offene Inhalte (Operator-Notiz)
|
||||
|
||||
Diese Punkte gehoeren in das Wochenend-Onboarding-Gespraech und sind nicht Teil dieser Familien-Seite:
|
||||
|
||||
| Status | Aufgabe |
|
||||
|---|---|
|
||||
| offen | Pro Familien-Konto Benutzernamen und Start-Passwort an die Person uebergeben |
|
||||
| offen | 2FA-App-Empfehlung pro Person festlegen (z. B. 2FAS / Aegis / Bitwarden Authenticator) |
|
||||
| offen | Pro Familien-Konto Benutzernamen und Start-Passwort persoenlich uebergeben (Vaultwarden Familien-Organisation als Uebergabeweg) |
|
||||
| offen | 2FA-App-Empfehlung pro Person festlegen (zum Beispiel Bitwarden Authenticator, Aegis, 2FAS) |
|
||||
| offen | Vaultwarden Familien-Organisation einrichten und Mitglieder einladen |
|
||||
| offen | Immich Mobile Backup mit jedem Familien-Geraet testen |
|
||||
| offen | Immich Mobile Backup mit jedem Familien-Geraet einmal gemeinsam ausprobieren |
|
||||
| offen | Scan-/Inbox-Anleitung fuer Paperless ergaenzen, sobald der Workflow final ist |
|
||||
| offen | Einladungstermin Wochenende mit konkretem Datum festlegen |
|
||||
|
||||
## Bewusst nicht versprochen
|
||||
|
||||
Damit niemand spaeter enttaeuscht ist, hier kurz, was die Seite **nicht** verspricht:
|
||||
|
||||
- Es gibt aktuell **kein** Einheits-Login fuer alle Apps. Jede App hat ihre eigene Anmeldung. Eine Vereinheitlichung ist als Idee notiert, aber zeitlich noch nicht geplant.
|
||||
- Es gibt **keine** Garantie, dass eine App 24/7 verfuegbar ist. Es ist ein Heim-Server, kein Rechenzentrum.
|
||||
- Es gibt **keinen** automatischen Support per Hotline. Probleme gehen an Michi.
|
||||
- Es gibt **kein** Werbe-Konto und keinen Versand deiner Daten an Externe. Alles bleibt zuhause.
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# Family-View Dashboard - Spezifikation
|
||||
|
||||
Status: **Spezifikation (Doku-only)**, kein Grafana-JSON in diesem Schritt.
|
||||
Audit-Bezug: `docs/AUDIT_2026-05-25.md` Finding **F-08** (Alerts/Sichtbarkeit) und das Sprint-3-TODO "Family-View Dashboard definieren" aus `docs/AUDIT_2026-05-25_TODO.md`.
|
||||
|
||||
## Zweck
|
||||
|
||||
Ein Grafana-Dashboard, das beim Morgen-Check in unter 30 Sekunden zeigt, ob das Homelab gesund ist. Zielgruppe ist primaer der Operator. Wenn die Familie es zufaellig anschaut, soll niemand erschrecken: ueberall gruene Felder bedeuten "alles in Ordnung", ohne dass man die Technik dahinter verstehen muss.
|
||||
|
||||
Das Dashboard ist die Konsolidierung des morgendlichen Pruefablaufs:
|
||||
|
||||
- Sind die wichtigsten Apps erreichbar?
|
||||
- Hat das Backup gestern Nacht funktioniert?
|
||||
- Wann laufen die Zertifikate aus?
|
||||
- Sind die Disks ausreichend frei?
|
||||
- Laufen die kritischen Container?
|
||||
|
||||
## Abgrenzung
|
||||
|
||||
Diese Datei beschreibt nur Layout, Datenquellen und PromQL-Queries. Die JSON-Datei `monitoring/grafana/dashboards/family-view.json` wird **bewusst noch nicht** angelegt, weil:
|
||||
|
||||
- Es noch keine Live-Pruefung gegen die echte Grafana-Instanz gab.
|
||||
- Die Alert-Regeln (Borg-Stale, Cert-Expiry, Container-Down) sind laut `docs/AUDIT_2026-05-25_TODO.md` Sprint 3 selbst noch im "in Arbeit (Regeln vorbereitet)"-Status.
|
||||
- Bei einem halbgaren Dashboard-JSON entstehen mehr Wartungsfragen als Klarheit.
|
||||
|
||||
Die JSON-Datei wird angelegt, sobald (a) die genannten Metriken stabil verfuegbar sind und (b) ein erster manueller Build im Grafana-UI das Layout bestaetigt hat.
|
||||
|
||||
## Datenquellen
|
||||
|
||||
Authoritativ ist `monitoring/grafana/provisioning/datasources/datasources.yml`. Das Dashboard nutzt nur die schon provisionierten Datasources:
|
||||
|
||||
- `Prometheus` - Blackbox, node-exporter, cAdvisor, Traefik-Metrics
|
||||
- optional `Loki` - Log-Volume-Spike als Zusatz-Panel
|
||||
- bewusst nicht: `InfluxDB 3 Core` (das ist Home-Assistant-/Ecowitt-Sicht, nicht Homelab-Health)
|
||||
|
||||
## Layout (4x4 Grid, mobile-vertraeglich)
|
||||
|
||||
| Zeile | Panel | Breite (Grafana w) | Hoehe (Grafana h) |
|
||||
|---|---|---:|---:|
|
||||
| 1 | Endpoints up (Stat, gross gruen/rot) | 12 | 5 |
|
||||
| 1 | Backup heute Nacht (Stat) | 6 | 5 |
|
||||
| 1 | Naechster Cert-Ablauf (Stat, Tage) | 6 | 5 |
|
||||
| 2 | Kritische Container running (Stat-Liste) | 12 | 6 |
|
||||
| 2 | Disk-Fuellung (Bargraph, je Mountpoint) | 12 | 6 |
|
||||
| 3 | Endpoint-Tabelle (Table: Host, Status, Latenz) | 24 | 8 |
|
||||
| 4 | Cert-Tage-Tabelle (Table: Host, Tage bis Ablauf) | 12 | 6 |
|
||||
| 4 | Container-Status-Tabelle (Table: kritischer Container, Running, letztes Restart) | 12 | 6 |
|
||||
|
||||
Dashboard-Metadaten:
|
||||
|
||||
- UID: `homelab-family-view`
|
||||
- Title: `Homelab / Family View`
|
||||
- Tags: `homelab`, `family-view`, `morning-check`
|
||||
- Refresh: `30s`
|
||||
- Default-Zeitfenster: `now-24h` bis `now`
|
||||
- Folder: `Homelab`
|
||||
|
||||
## Panel-Spezifikation
|
||||
|
||||
### Panel 1: Endpoints up
|
||||
|
||||
- Type: `stat`
|
||||
- Title: `Apps online`
|
||||
- Query: `sum(probe_success{job="blackbox-http"})`
|
||||
- Anzeige: gruene Zahl bei Gesamtzahl, Wechsel auf rot wenn `< Soll-Anzahl`.
|
||||
- Threshold: Soll-Anzahl wird aus `monitoring/blackbox/blackbox.yml` und Prometheus-Scrape-Liste abgeleitet (zum Doku-Zeitpunkt 19 HTTPS-Ziele laut `docs/MIGRATION_LOG.md` 2026-05-25-Monitoring-Konsolidierung).
|
||||
- Subtitel im Panel: `von <N> erreichbar`. (Soll-Wert wird beim Bau aus dem aktuellen Target-Count gesetzt; nicht hartcoden.)
|
||||
|
||||
### Panel 2: Backup heute Nacht
|
||||
|
||||
- Type: `stat`
|
||||
- Title: `Borg-Lauf`
|
||||
- Query (sobald Borg-Stale-Metrik im Textfile-Collector live ist):
|
||||
```promql
|
||||
(time() - homelab_borg_last_completed_timestamp_seconds) / 3600
|
||||
```
|
||||
- Einheit: `h`
|
||||
- Threshold:
|
||||
- 0-26 h gruen
|
||||
- 26-30 h gelb
|
||||
- >30 h rot
|
||||
- Subtitel im Panel: `Stunden seit letztem completed-Lauf`.
|
||||
- Fallback bis Metrik live: Panel zeigt `n/a`, Doku-Hinweis in der Beschreibung.
|
||||
|
||||
### Panel 3: Naechster Cert-Ablauf
|
||||
|
||||
- Type: `stat`
|
||||
- Title: `Cert laeuft in`
|
||||
- Query:
|
||||
```promql
|
||||
min((probe_ssl_earliest_cert_expiry{job="blackbox-http"} - time()) / 86400)
|
||||
```
|
||||
- Einheit: `d` (Tage)
|
||||
- Threshold:
|
||||
- >14 gruen
|
||||
- 7-14 gelb
|
||||
- <7 rot
|
||||
- Subtitel: `Tage bis kleinste Restlaufzeit aller geprueften Hosts`.
|
||||
|
||||
### Panel 4: Kritische Container running
|
||||
|
||||
- Type: `stat`
|
||||
- Title: `Kritische Container`
|
||||
- Query (sobald Container-Up-Metrik live ist):
|
||||
```promql
|
||||
sum(homelab_critical_container_running)
|
||||
```
|
||||
- Threshold: erwartete Anzahl gruen, jeder fehlende Container rot.
|
||||
- Subtitel: `von <N> erwartet`. Erwartete Liste pflegen wir in `services/posture-check` / Textfile-Exporter (siehe `docs/AUDIT_2026-05-25_TODO.md` Sprint 3 "Container-Down-Alert").
|
||||
- Fallback: cAdvisor-Query als Naeherung, solange Textfile-Metrik noch nicht produktiv ist:
|
||||
```promql
|
||||
count(rate(container_last_seen{name=~"traefik|authelia|postgresql17|Redis|gitea|komodo-core|komodo-mongo|komodo-periphery|monitoring-prometheus|monitoring-grafana|monitoring-loki|monitoring-alertmanager"}[5m]) > 0)
|
||||
```
|
||||
|
||||
### Panel 5: Disk-Fuellung
|
||||
|
||||
- Type: `bargauge`
|
||||
- Title: `Disk-Fuellung`
|
||||
- Query:
|
||||
```promql
|
||||
100 * (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})
|
||||
```
|
||||
- Anzeige: pro Mountpoint, sortiert absteigend.
|
||||
- Threshold:
|
||||
- <70 gruen
|
||||
- 70-85 gelb
|
||||
- >85 rot
|
||||
- Subtitel: `Prozent belegt`.
|
||||
|
||||
### Panel 6: Endpoint-Tabelle
|
||||
|
||||
- Type: `table`
|
||||
- Title: `Endpoint-Status`
|
||||
- Spalten:
|
||||
- Host (Instance)
|
||||
- Status (`UP` / `DOWN`)
|
||||
- Antwortzeit (probe_duration_seconds)
|
||||
- Queries:
|
||||
- `probe_success{job="blackbox-http"}` -> Mapping: `1` -> `UP` (gruen), `0` -> `DOWN` (rot)
|
||||
- `probe_duration_seconds{job="blackbox-http"}` -> Sekunden
|
||||
- Sortierung: DOWN oben, dann nach Antwortzeit absteigend.
|
||||
|
||||
### Panel 7: Cert-Tage-Tabelle
|
||||
|
||||
- Type: `table`
|
||||
- Title: `Cert-Tage bis Ablauf`
|
||||
- Spalten: Host, Tage
|
||||
- Query:
|
||||
```promql
|
||||
(probe_ssl_earliest_cert_expiry{job="blackbox-http"} - time()) / 86400
|
||||
```
|
||||
- Sortierung: aufsteigend (am ehesten ablaufende oben).
|
||||
- Color-Mapping wie Panel 3.
|
||||
|
||||
### Panel 8: Container-Status-Tabelle
|
||||
|
||||
- Type: `table`
|
||||
- Title: `Kritische Container`
|
||||
- Spalten: Container, Running (1/0), letztes Restart (Sekunden seit Start)
|
||||
- Queries:
|
||||
- sobald Textfile-Metrik live: `homelab_critical_container_running` (Label `name`)
|
||||
- Fallback aus cAdvisor: `container_start_time_seconds{name=~"<Whitelist>"}`
|
||||
- Sortierung: nicht-running zuerst.
|
||||
|
||||
## Spaeter ergaenzbar (nicht Teil der ersten Version)
|
||||
|
||||
- Loki-Log-Volume-Spike-Panel
|
||||
- node_exporter Memory-Saturation-Panel
|
||||
- Plex-Sessions (nur wenn Plex-Exporter eingerichtet ist; aktuell nicht geplant)
|
||||
- Immich Asset-Wachstum (eigenes Dashboard, nicht Family-View)
|
||||
|
||||
## Build-Reihenfolge fuer den spaeteren JSON
|
||||
|
||||
Wenn das JSON gebaut wird, bitte in dieser Reihenfolge:
|
||||
|
||||
1. Sicherstellen, dass alle Metriken aus den Queries oben in Prometheus auffindbar sind (`/graph` Smoke-Test).
|
||||
2. Dashboard in Grafana-UI manuell zusammenklicken; Layout an dieser Spezifikation entlang.
|
||||
3. JSON exportieren, in `monitoring/grafana/dashboards/family-view.json` ablegen.
|
||||
4. Provisioning-Provider laesst die Datei automatisch laden (siehe `monitoring/grafana/provisioning/dashboards/dashboards.yml`).
|
||||
5. Bei jeder Schema-Aenderung Doku hier nachziehen, damit Spec und JSON nicht driften.
|
||||
|
||||
## Smoke-Test nach Aktivierung
|
||||
|
||||
- Dashboard laedt unter `https://monitoring.kaleschke.info/d/homelab-family-view/`.
|
||||
- Alle 8 Panels rendern ohne `No data`.
|
||||
- Im Normalbetrieb erscheinen Panel 1-5 vollstaendig gruen.
|
||||
- Ein bewusster Test-Stale-Borg oder ein Container-Stop laesst die zugehoerigen Panels auf gelb/rot wechseln.
|
||||
|
||||
## Was das Dashboard NICHT ersetzt
|
||||
|
||||
- ntfy-Alerts: das Dashboard ist passiv (Pull), ntfy ist aktiv (Push). Beide sind notwendig.
|
||||
- DR-Doku: `docs/DISASTER_RECOVERY.md` bleibt die Recovery-Quelle.
|
||||
- Restore-Tests: `docs/RESTORE_DRILL_ROUTINE.md` ist die Kadenz, die das Dashboard nicht ersetzt.
|
||||
- Familien-Onboarding: `docs/FAMILY_ONBOARDING.md` ist die Doku fuer die Familie, dieses Dashboard ist Operator-Tool.
|
||||
@@ -0,0 +1,94 @@
|
||||
# FRITZ!Box Portfreigaben - Korrektur-Vorbereitung
|
||||
|
||||
Status: **Vorbereitung (Doku-only)**, 2026-05-27. Keine Router-Aenderung.
|
||||
Audit-Bezug: `docs/AUDIT_2026-05-25_TODO.md` Sprint 4 ("FRITZ!Box-Portfreigaben gegen Repo-Soll abgleichen") und `docs/NETWORK_INVENTORY.md`.
|
||||
|
||||
## Aktueller FRITZ!Box-Befund (2026-05-27)
|
||||
|
||||
Aus dem Operator-Live-Check der FRITZ!Box-UI:
|
||||
|
||||
- aktiv: `80/tcp` -> `192.168.178.58`
|
||||
- aktiv: `443/tcp` -> `192.168.178.58`
|
||||
- fehlt: `222/tcp` -> `192.168.178.58` (Gitea-SSH)
|
||||
- zusaetzlich gemeldet: eine Portfreigabe durch das Geraet `PC-192-168-178-71` (Selbst-Freigabe per UPnP)
|
||||
|
||||
## Soll-Stand laut Repo
|
||||
|
||||
`docs/NETWORK_INVENTORY.md` definiert genau zwei aktive Portfreigaben:
|
||||
|
||||
| Erwartete Freigabe | Ziel | Begruendung |
|
||||
|---|---|---|
|
||||
| `443/tcp` -> `192.168.178.58:443` | Traefik HTTPS | einziger Public-HTTPS-Einstieg, Wildcard-Zert ueber Cloudflare-DNS-Challenge |
|
||||
| `222/tcp` -> `192.168.178.58:222` | Gitea SSH | Git-SSH-Push/Pull; dokumentierte Ausnahme |
|
||||
|
||||
Port `80/tcp` ist im Cloudflare-DNS-Challenge-Modell **nicht** notwendig.
|
||||
|
||||
## Drei Korrektur-Punkte
|
||||
|
||||
### 1. `80/tcp` entfernen
|
||||
|
||||
Begruendung:
|
||||
|
||||
- ACME laeuft als Cloudflare-DNS-Challenge (`traefik/docker-compose.yml`), nicht als HTTP-01.
|
||||
- Traefik leitet intern jeden HTTP-Request auf `https://` weiter; ein WAN-`80`-Listener bietet keinen Mehrwert, oeffnet aber einen zusaetzlichen Angriffsvektor (Header-/Method-Scanning, Open-Redirect-Versuche bevor TLS terminiert).
|
||||
- Innerhalb des LAN funktioniert die Browser-Auto-HTTPS-Umleitung weiter ueber AdGuard-DNS.
|
||||
|
||||
Empfehlung: WAN-Eintrag `80/tcp` in FRITZ!Box-UI **entfernen** nach Operator-Go.
|
||||
|
||||
Validierung nach Aenderung:
|
||||
|
||||
```bash
|
||||
# WAN-seitiger Test, idealerweise von einem Geraet im Mobilfunknetz oder Tailscale-Exit-Node
|
||||
curl -sI http://kaleschke.info/ # erwartet: Connection refused / Timeout
|
||||
curl -sI https://vault.kaleschke.info/ # erwartet: HTTP/2 200 oder Authelia-Redirect
|
||||
```
|
||||
|
||||
### 2. `222/tcp` ergaenzen (nur wenn externes Git-SSH wirklich gewuenscht)
|
||||
|
||||
Frage an Operator: Wird `git@git.kaleschke.info -p 222` von extern gebraucht? Hinweise:
|
||||
|
||||
| Pro `222/tcp` extern | Contra `222/tcp` extern |
|
||||
|---|---|
|
||||
| Push/Pull vom unterwegs-Laptop ohne Tailscale | Tailscale ist schon der Operator-Pfad, deckt das voll ab |
|
||||
| GitHub-Mirror-Bootstrap funktioniert dann auch ohne Tailscale | GitHub-Push-Mirror laeuft automatisch von Gitea aus, braucht kein WAN-SSH |
|
||||
| Externe Webhooks gegen Git push (nicht in Nutzung) | weniger Angriffsflaeche fuer SSH-Brute-Force |
|
||||
|
||||
Empfehlung: `222/tcp` **nicht** ergaenzen, solange Tailscale stabil verfuegbar ist. Stattdessen `docs/NETWORK_INVENTORY.md` und `HOMELAB_ARCHITECTURE_MASTER_V2.md` darauf abgleichen, dass Gitea-SSH bewusst LAN/Tailscale-only ist.
|
||||
|
||||
Wenn Operator entscheidet, `222/tcp` doch extern zu oeffnen: zusaetzlich SSH-Login auf Key-only setzen, Brute-Force-Limits in Gitea pruefen, `docs/NETWORK_INVENTORY.md` "Erwartete Freigabe"-Tabelle aktualisieren.
|
||||
|
||||
### 3. UPnP-Selbstfreigabe von `PC-192-168-178-71` deaktivieren
|
||||
|
||||
Begruendung:
|
||||
|
||||
- Geraete-initiierte Portfreigaben (UPnP) sind ausserhalb der Repo-Sollkonfiguration.
|
||||
- Welcher Port von welchem Programm geoeffnet wurde, ist aus der FRITZ!Box-UI heraus nicht versionierbar.
|
||||
- Wenn der Port gebraucht wird, gehoert er als bewusste Operator-Freigabe in `docs/NETWORK_INVENTORY.md`.
|
||||
|
||||
Empfehlung in zwei Stufen:
|
||||
|
||||
1. FRITZ!Box-UI: in den Geraete-Details fuer `PC-192-168-178-71` die aktuelle Selbstfreigabe-Liste pruefen und mit dem Operator besprechen.
|
||||
2. Wenn der Port nicht gebraucht wird: Selbstfreigabe deaktivieren. Optional: UPnP global pro Geraet abschalten ("Selbststaendige Portfreigaben fuer dieses Geraet erlauben" abwaehlen).
|
||||
|
||||
## Schutzregeln
|
||||
|
||||
- Keine Router-Aenderung ohne ausdrueckliches Operator-Go.
|
||||
- Nach jeder Aenderung: `docs/NETWORK_INVENTORY.md` Abschnitt "FRITZ!Box (WAN -> Host)" gegen den neuen UI-Stand abgleichen.
|
||||
- Aenderung in `docs/MIGRATION_LOG.md` als kurzer Eintrag dokumentieren (was/warum/Validierung).
|
||||
- Bei `80/tcp`-Entfernung kurz prufen, ob irgendein externer Dienst noch HTTP-01 nutzen wollte (sollte nicht der Fall sein).
|
||||
|
||||
## Nicht Teil dieser Vorbereitung
|
||||
|
||||
- FRITZ!OS-Update 8.21 -> aktuell. Das ist eigenes Service-Fenster und braucht WAN/Tailscale-Aufbau-Beobachtung.
|
||||
- IPv6-Exposure. Wenn Telekom IPv6 zustellt und Apps via Cloudflare-AAAA erreichbar sind, kann WAN-Filter pro Port noetig werden. Separater Doku-Punkt in `docs/NETWORK_INVENTORY.md` Offene Entscheidungen.
|
||||
- Mobilfunk-Failover-Stick. Bewusst nicht eingerichtet.
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
| Status | Punkt | Naechster Schritt |
|
||||
|---|---|---|
|
||||
| offen (Operator-Go) | `80/tcp` entfernen | FRITZ!Box-UI, danach `docs/NETWORK_INVENTORY.md` aktualisieren |
|
||||
| offen (Operator-Go) | `222/tcp` Entscheidung | Operator klaert: extern noetig oder Tailscale-only |
|
||||
| offen (Operator-Go) | UPnP-Freigabe `PC-192-168-178-71` | FRITZ!Box-UI Geraete-Detail pruefen |
|
||||
| offen | FRITZ!OS 8.21 Update | Service-Fenster, separat geplant |
|
||||
| offen | IPv6-Exposure pruefen | bei naechstem WAN-Touch mit erfassen |
|
||||
@@ -17,6 +17,27 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab
|
||||
|
||||
## Historische Meilensteine
|
||||
|
||||
### 2026-05-27 - Vorbereitungsdokumente FRITZ!Box-Korrektur und Off-site-Optionen
|
||||
|
||||
- Reine Doku-Aenderung; kein Router-, Provider- oder Host-Eingriff.
|
||||
- `docs/FRITZBOX_PORT_CORRECTION_PLAN.md` neu angelegt: Korrektur-Plan fuer drei Punkte (`80/tcp` entfernen, `222/tcp` nicht ergaenzen solange Tailscale stabil, UPnP-Selbstfreigabe `PC-192-168-178-71` deaktivieren). Operator-Go ausstehend; jede UI-Aenderung wird gesondert dokumentiert.
|
||||
- `docs/OFFSITE_BACKUP_OPTIONS.md` neu angelegt: Entscheidungsvorlage fuer zweites Off-site-Ziel mit drei Optionen (rsync.net Borg-Plan, BorgBase EU2, rotierende Cold-Platte). Bewertung gegen Provider-Trennung, Standort, Preis und Konto-Risiko; Empfehlung rsync.net oder Cold-Platte; BorgBase EU2 explizit nicht empfohlen wegen gleichem Anbieter. Kein Provider gebucht, keine Kosten ausgeloest.
|
||||
- `docs/REPO_MAP.md` um beide neuen Dokumente ergaenzt.
|
||||
- `docs/AUDIT_2026-05-25_TODO.md` Sprint 4 (FRITZ!Box) und Sprint 7 (Off-site) mit Verweis auf die neuen Vorbereitungsdokumente nachgezogen.
|
||||
|
||||
### 2026-05-27 - Doku-Sprint Bootstrap / Family-View / Onboarding / Drill-Routine
|
||||
|
||||
- Reine Doku-Aenderung; kein Compose-, Secret-, Host- oder Router-Eingriff.
|
||||
- `docs/SERVICES_RECOVERY.md` "Komodo Bootstrap" auf linearen Stufenpfad A-F ausgebaut: Recovery-Anker bleibt `ops/komodo/docker-compose.yml`, Self-Stack ist explizit kein Anker, Secret-Restore-Reihenfolge verweist auf `docs/SECRETS_MAP.md` Stack-ENV-only-Sektion, Validierungs-Kommandos ergaenzt. Trockenlauf-Idee als Folgeaufgabe eingetragen, kein Repo-Skript dafuer.
|
||||
- `docs/DISASTER_RECOVERY.md` Phase 4 Stufe 3 verweist explizit auf den Bootstrap-Pfad in `docs/SERVICES_RECOVERY.md` und auf die Stack-ENV-only-Sektion in `docs/SECRETS_MAP.md`.
|
||||
- `docs/FAMILY_VIEW_DASHBOARD.md` neu angelegt: Spezifikation fuer `homelab-family-view`-Dashboard, 8 Panels (Endpoints up, Borg-Frische, Cert-Tage, Kritische Container, Disk-Fuellung, Endpoint-Tabelle, Cert-Tabelle, Container-Tabelle), PromQL-Queries, Thresholds, Build-Reihenfolge. Bewusst noch **kein** `monitoring/grafana/dashboards/family-view.json` angelegt, weil Borg-Stale-/Cert-Expiry-/Container-Down-Metriken laut Sprint 3 noch "in Arbeit" sind.
|
||||
- `docs/FAMILY_ONBOARDING.md` final redigiert: Status auf "Final-Stand vor Wochenend-Einladung", 2FA-Beschreibung auf App-eigene 2FA praezisiert (kein SSO-Versprechen, weil Authelia-OIDC weiter geparkt ist), neuer "Bewusst nicht versprochen"-Block (kein Einheits-Login, kein 24/7-SLA, kein Hotline-Support, keine Datenweitergabe).
|
||||
- `docs/RESTORE_DRILL_ROUTINE.md` neu angelegt: Drei-Stufen-Modell (Freshness woechentlich / Mini-Restore monatlich-bimonatlich / DR-Sanity quartalsweise), Quartals-Kadenz Q1-Q4 mit Dienst-Rotation, bestaetigte Mini-Restores (Vaultwarden, Gitea, Paperless 2026-05-07; Immich 2026-05-27), 10-Punkte-Sanity-Check, Abbruch-Regel mit Verweis auf `docs/GITOPS_DRIFT_RUNBOOK.md`. Kein Host-Schedule angelegt, nur Doku.
|
||||
- `ops/restore-tests/schedule.md` verweist jetzt auf `docs/RESTORE_DRILL_ROUTINE.md` als Quelle der Quartals-Belegung.
|
||||
- `docs/REPO_MAP.md` um `docs/FAMILY_VIEW_DASHBOARD.md`, `docs/RESTORE_DRILL_ROUTINE.md` und `docs/IMMICH_RESTORE_TEST.md` ergaenzt.
|
||||
- `docs/AUDIT_2026-05-25_TODO.md` aktualisiert: Sprint 2 "Komodo-Bootstrap-Pfad beschreiben", Sprint 3 "Family-View Dashboard definieren", Sprint 4 "Familien-Onboarding schreiben" und Sprint 7 "Restore-Lab-Drill quartalsweise dokumentieren" jeweils auf "erledigt".
|
||||
- Geparkte Punkte bleiben unveraendert: Authelia-2FA/OIDC/CrowdSec, Nextcloud-Haertung, Hermes (Review 2026-07-25), USV-Anschaffung.
|
||||
|
||||
### 2026-05-27 - Immich Restore-Smoke-Test praktisch verifiziert (F-11)
|
||||
|
||||
- Erster echter Immich-Restore-Smoke-Test gegen das produktive Borg-Archiv erfolgreich: `Tägliche-Sicherung-2026-05-27T04:30:06.778`, Report `/mnt/user/backups/restore-reports/immich-2026-05-27.md`.
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
# Zweites Offsite-Backup-Ziel - Entscheidungsvorlage
|
||||
|
||||
Status: **Entscheidungsvorlage (Doku-only)**, 2026-05-27. Kein Provider gebucht, keine Kosten ausgeloest.
|
||||
Audit-Bezug: `docs/AUDIT_2026-05-25.md` Finding **F-03** und `docs/AUDIT_2026-05-25_TODO.md` Sprint 7.
|
||||
|
||||
## Zweck
|
||||
|
||||
Aktuell laeuft das Off-site-Backup bei genau einem Anbieter (**Hetzner Storage Box**). Diese Vorlage stellt drei realistische Optionen fuer ein **zweites** Off-site-Ziel gegenueber. Die Entscheidung trifft der Operator; dieses Dokument trifft sie nicht.
|
||||
|
||||
`H:/` am Windows-PC bleibt **kein** Offsite-Ersatz (siehe `docs/CAPACITY_AND_LIFECYCLE.md`). H:/ ist Nearline-Kopie am gleichen Standort.
|
||||
|
||||
## Anforderungen an das zweite Ziel
|
||||
|
||||
| Anforderung | Begruendung |
|
||||
|---|---|
|
||||
| **anderer Anbieter als Hetzner** | Provider-Risiko (Account-Sperre, Insolvenz, Region-Outage) wird sonst nicht reduziert |
|
||||
| **anderer physischer Standort** als Unraid-Host | Brand-/Diebstahl-/Wasser-Schutz |
|
||||
| **Borg-kompatibel** (SSH + Repo-Layout) | bestehendes Borg-UI-Setup soll wiederverwendbar bleiben |
|
||||
| **bezahlbar im Privatrahmen** | grobe Zielgroesse: < 10 EUR / Monat fuer ~1 TB |
|
||||
| **stabil ueber Monate** | wenig Eingriff, keine taeglichen Quirks |
|
||||
| **keine Konto-Komplexitaet** | 2FA-Recovery muss sauber, ohne Telefon-Nummer-Hacks etc. moeglich sein |
|
||||
|
||||
## Drei Optionen
|
||||
|
||||
### Option A - rsync.net Borg-Plan
|
||||
|
||||
- **Was:** seit Jahren etablierter Anbieter mit dediziertem Borg-Plan (eingebaute `borg`-Binary, SSH-Account, Snapshot-Schutz).
|
||||
- **Zielanbindung:** `borg init --encryption=repokey-blake2 user@hostname:repo`.
|
||||
- **Standort:** Schweiz/USA (je nach Konto-Region).
|
||||
- **Preis (Stand 2026, grob):** ~10-15 USD pro Monat fuer 1 TB; Mindestbestelldauer keine.
|
||||
- **Vorteile:** Borg-First, ZFS-Snapshots als zusaetzlicher Schutz vor Repo-Loeschung, sehr lange Track-Record, keine SMB-/CIFS-Quirks.
|
||||
- **Nachteile:** USD-Preis, Standort ausserhalb EU je nach Konto, etwas teurer als reine Storage Boxes.
|
||||
- **Konto-Risiko:** unabhaengig von Hetzner-Konto.
|
||||
|
||||
### Option B - BorgBase EU2 (zweite Region beim gleichen Borg-Spezialisten)
|
||||
|
||||
- **Was:** BorgBase ist Borg-as-a-Service mit mehreren Regionen.
|
||||
- **Zielanbindung:** identisch zu bestehendem Borg-UI-Pfad.
|
||||
- **Standort:** zweite EU-Region als EU1.
|
||||
- **Preis (Stand 2026, grob):** ~10 EUR / Monat fuer ~1 TB.
|
||||
- **Vorteile:** identisches Borg-Modell, geringer Lernaufwand, einfache Web-UI.
|
||||
- **Nachteile:** Anbieter-Risiko nicht vollstaendig getrennt (gleicher Anbieter, andere Region). Bei Account-Sperre/Insolvenz waeren beide Ziele gleichzeitig betroffen.
|
||||
- **Konto-Risiko:** **gleicher** Anbieter, **anderes** Geo-Risiko.
|
||||
|
||||
### Option C - Rotierende Cold-Wechselplatte ausser Haus
|
||||
|
||||
- **Was:** zweite externe HDD (z. B. 2x WD Elements 4 TB), die im monatlichen Wechsel zwischen Heim-LAN und vertrauter dritter Person (Familie, Schliessfach, Buero) rotiert.
|
||||
- **Zielanbindung:** Borg-Repo lokal auf der eingesteckten Platte; Backup-Lauf nur wenn die Platte gerade vor Ort ist.
|
||||
- **Standort:** echtes Ausserhaus, dazwischen offline (Air-Gap).
|
||||
- **Preis (einmalig):** zwei Platten ~250 EUR, keine laufenden Kosten.
|
||||
- **Vorteile:** echtes Air-Gap, keine Provider-Abhaengigkeit, keine Bandbreitenfrage, keine Konto-Risiken.
|
||||
- **Nachteile:** manuelle Disziplin noetig, Recovery-Zeit haengt davon ab, dass die Platte gerade erreichbar ist. Nicht so taggenau wie Cloud-Borg.
|
||||
- **Konto-Risiko:** keines (keine Provider-Bindung).
|
||||
|
||||
## Bewertung gegen die Anforderungen
|
||||
|
||||
| Anforderung | Hetzner (Ist) | Option A rsync.net | Option B BorgBase EU2 | Option C Cold-Platte |
|
||||
|---|---|---|---|---|
|
||||
| Anderer Anbieter | - | ja | nein (gleicher) | ja (keiner) |
|
||||
| Anderer Standort | - | ja | ja | ja |
|
||||
| Borg-kompatibel | ja | ja | ja | ja |
|
||||
| Preis < 10 EUR/Monat | ja | grenzwertig | ja | einmalig ~250 EUR |
|
||||
| Stabilitaet | hoch | hoch | hoch | Operator-Disziplin abhaengig |
|
||||
| 2FA/Konto-Recovery | OK | OK | OK | n/a |
|
||||
|
||||
## Empfehlung (nicht Entscheidung)
|
||||
|
||||
Wenn der Operator die geringste Bedienung bei maximalem Provider-getrennten Schutz will: **Option A rsync.net**. Echte Anbieter-Trennung gegenueber Hetzner, Borg-First-Anbieter, ZFS-Snapshot-Schutz, keine zusaetzliche Hardware noetig.
|
||||
|
||||
Wenn Air-Gap und Null-Provider-Abhaengigkeit am wichtigsten sind und der Operator die monatliche Rotation tatsaechlich diszipliniert macht: **Option C Cold-Platte**.
|
||||
|
||||
**Option B (BorgBase EU2) wird nicht empfohlen** als zweites Ziel, weil das das Provider-Risiko nicht reduziert.
|
||||
|
||||
## Was vor einer Buchung zu tun ist
|
||||
|
||||
1. Operator-Entscheidung Option A vs. C dokumentieren (kein Provider-Kontakt vor Entscheidung).
|
||||
2. Falls Option A:
|
||||
- Konto bei rsync.net anlegen, Borg-Plan waehlen.
|
||||
- SSH-Key vom Borg-UI-Container exportieren bzw. dediziertes Key-Pair erzeugen.
|
||||
- `borg init` gegen das neue Repo durchfuehren (separate Passphrase oder gleiche - bewusst entscheiden).
|
||||
- Borg-UI um zweites Repository erweitern (separater Eintrag, kein Replace).
|
||||
- Schedule pruefen: erstes Vollbackup als One-Shot, danach inkrementell.
|
||||
- `docs/SECRETS_MAP.md` und `docs/EXTERNAL_DEPENDENCIES.md` um neuen Provider ergaenzen.
|
||||
- `docs/RESTORE_MATRIX.md` und `docs/STORAGE_LAYOUT.md` Backup-Ziel-Liste aktualisieren.
|
||||
3. Falls Option C:
|
||||
- zwei Platten beschaffen, Filesystem XFS oder ext4 (kein NTFS).
|
||||
- Rotations-Plan in `docs/STORAGE_LAYOUT.md` §8.1 ergaenzen.
|
||||
- Borg-Repo-Init pro Platte; Borg-UI um lokales Repo erweitern (nur aktiv wenn Platte eingesteckt).
|
||||
- Operator-Disziplin: monatliche Rotation als Kalender-Reminder.
|
||||
|
||||
## Was bewusst NICHT in dieser Vorlage steht
|
||||
|
||||
- Konkrete Hetzner-Konto-Daten, rsync.net-Accountnamen, IBANs, Telefonnummern. Diese Daten gehoeren nirgendwo in dieses Repo.
|
||||
- Borg-Passphrasen. Bleiben ausserhalb des Repos.
|
||||
- "Migrieren weg von Hetzner" als Option. Hetzner bleibt; das zweite Ziel ist Ergaenzung, nicht Ablosung.
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
| Status | Punkt | Naechster Schritt |
|
||||
|---|---|---|
|
||||
| offen | Entscheidung Option A vs. C | Operator |
|
||||
| offen | Budget-Freigabe | Operator |
|
||||
| offen | Provider-/Hardware-Beschaffung | nach Entscheidung |
|
||||
| offen | Schedule-Anpassung in `ops/borg-ui` | nach Provider-Bereitstellung |
|
||||
@@ -38,6 +38,11 @@ Secret-Werte werden hier nicht dokumentiert. Aufgefuehrt werden nur Variablennam
|
||||
| `docs/EXTERNAL_DEPENDENCIES.md` | Externe Provider, Konten, Ausfall-Szenarien und kritische Off-Repo-Abhaengigkeiten |
|
||||
| `docs/CAPACITY_AND_LIFECYCLE.md` | Capacity-Schwellen, Wachstum, Upgrade-Trigger und Restore-Zeitziele |
|
||||
| `docs/FAMILY_ONBOARDING.md` | Familienorientierte Nutzungsdoku ohne Operator-Details |
|
||||
| `docs/FAMILY_VIEW_DASHBOARD.md` | Spezifikation fuer das Grafana Family-View-Dashboard (Doku-only, kein JSON) |
|
||||
| `docs/RESTORE_DRILL_ROUTINE.md` | Quartalsweise Restore-Drill-Routine, Tier-Belegung, DR-Sanity-Check |
|
||||
| `docs/IMMICH_RESTORE_TEST.md` | Operator-Overview Immich-Restore-Test, Erstlauf 2026-05-27 erfolgreich |
|
||||
| `docs/FRITZBOX_PORT_CORRECTION_PLAN.md` | Vorbereitungs-Doku fuer FRITZ!Box-Portfreigaben-Korrektur (kein Router-Eingriff) |
|
||||
| `docs/OFFSITE_BACKUP_OPTIONS.md` | Entscheidungsvorlage zweites Offsite-Backup-Ziel (rsync.net vs. BorgBase EU2 vs. Cold-Platte) |
|
||||
| `docs/AUDIT_2026-05-25_TODO.md` | Operative Arbeitsliste aus dem Audit vom 2026-05-25; Authelia-2FA bewusst geparkt |
|
||||
| `docs/ALERTING_MAP.md` | ntfy Topic-Konvention und Sender-Mapping fuer Homelab-Alerts |
|
||||
| `docs/ROLLBACK.md` | Rueckweg bei Fehlern im GitOps-Betrieb |
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# Restore-Drill Routine - KalliLab CORE
|
||||
|
||||
Status: **verbindliche Routine (Doku-only)**, 2026-05-27.
|
||||
Audit-Bezug: `docs/AUDIT_2026-05-25.md` Sprint 7 "Restore-Lab-Drill quartalsweise dokumentieren".
|
||||
Verwandte Docs: `docs/RESTORE_MATRIX.md`, `docs/RESTORE_HANDBOOK.md`, `docs/DISASTER_RECOVERY.md`, `ops/restore-tests/schedule.md`.
|
||||
|
||||
## Ziel
|
||||
|
||||
Sicherstellen, dass die Backup-Kette nicht nur weiter laeuft, sondern auch **wiederherstellbar** ist. Restore-Tests werden nicht ad-hoc gemacht, wenn ein Problem auftritt, sondern in einer planbaren Kadenz, damit das Vertrauen ueber die Zeit waechst und Drift fruehzeitig auffaellt.
|
||||
|
||||
Diese Datei beschreibt nur die **Routine** (wann, was, wie pruefen). Die operativen Anleitungen pro Dienst stehen in `docs/RESTORE_HANDBOOK.md` und den dienstspezifischen Runbooks unter `ops/restore-tests/<dienst>-runbook.md`.
|
||||
|
||||
## Drei-Stufen-Modell
|
||||
|
||||
| Stufe | Frequenz | Aufwand | Ziel |
|
||||
|---|---|---|---|
|
||||
| Freshness-Check | woechentlich | Minuten | Backup-Artefakte sind frisch, Reports lesbar |
|
||||
| Mini-Restore | monatlich/quartalsweise | 15-60 Min | Ein konkreter Dienst wird in isoliertem Test-Lab restauriert |
|
||||
| DR-Sanity-Check | quartalsweise | 1-2 h | Reihenfolge, Doku, Tier-Reihenfolge in der DR-Doku gegen Realitaet pruefen |
|
||||
|
||||
## Bestaetigte Mini-Restores
|
||||
|
||||
Wenn ein Mini-Restore zum ersten Mal sauber durchlaeuft, wird er hier als Referenz gefuehrt. Der Eintrag wird **nicht** entfernt, wenn er wiederholt wird; stattdessen aendert sich der Datums-Stand.
|
||||
|
||||
| Dienst | Erster bestaetigter Lauf | Letzter Erfolg | Report | Repo-Skript |
|
||||
|---|---|---|---|---|
|
||||
| Vaultwarden | 2026-05-07 | 2026-05-07 | `/mnt/user/backups/restore-reports/vaultwarden-2026-05-07.md` | `ops/restore-tests/vaultwarden-restore-test.sh` |
|
||||
| Gitea | 2026-05-07 | 2026-05-07 | `/mnt/user/backups/restore-reports/gitea-2026-05-07.md` | `ops/restore-tests/gitea-restore-test.sh` |
|
||||
| Paperless | 2026-05-07 | 2026-05-07 | `/mnt/user/backups/restore-reports/paperless-2026-05-07.md` | `ops/restore-tests/paperless-restore-test.sh` |
|
||||
| Immich | **2026-05-27** | **2026-05-27** | `/mnt/user/backups/restore-reports/immich-2026-05-27.md` | `ops/restore-tests/immich-restore-test.sh` |
|
||||
|
||||
Bei jedem weiteren Lauf wird die Spalte "Letzter Erfolg" aktualisiert.
|
||||
|
||||
## Quartals-Kadenz
|
||||
|
||||
Ein Kalenderjahr enthaelt vier Quartals-Drills. Jeder Quartals-Drill besteht aus dem Mini-Restore eines anderen Tier-2-Dienstes plus einem DR-Sanity-Check der Tier-1-Dienste.
|
||||
|
||||
| Quartal | Mini-Restore | DR-Sanity-Check Fokus |
|
||||
|---|---|---|
|
||||
| Q1 (Januar-Maerz) | `paperless` | Tier-1-Reihenfolge, Posture-Check-Status, Borg-Frische-Alerts |
|
||||
| Q2 (April-Juni) | `immich` | Komodo-Bootstrap-Pfad, Gitea-Bundles, Secrets-Pfad-Inventur |
|
||||
| Q3 (Juli-September) | `mealie` oder `nextcloud` (Operator-Wahl) | DNS-Pfad (AdGuard/Unbound/Tailscale), Cert-Expiry-Sicht |
|
||||
| Q4 (Oktober-Dezember) | `vaultwarden` oder `gitea` (Operator-Wahl) | Externe Abhaengigkeiten (Cloudflare, Hetzner, GitHub-Mirror), Off-site-Zweitziel-Diskussion |
|
||||
|
||||
Diese Liste ist bewusst auf Tier-2 und Tier-1-Dienste fokussiert. Tier-3-Dienste (Filebrowser, Glances, Scrutiny, Speedtest, Glance) werden im Drill nicht explizit ausgefuehrt, weil sie rebuildbar sind oder keinen kritischen Datenbestand haben.
|
||||
|
||||
### Q2 2026 - Konkrete Belegung
|
||||
|
||||
- Mini-Restore: **Immich (erledigt 2026-05-27)**.
|
||||
- DR-Sanity-Check (offen, vor Quartalsende 2026-06-30): Komodo-Bootstrap-Pfad gegen `docs/SERVICES_RECOVERY.md` durchgehen, Gitea-Bundles ueber `ops/borg-ui/scripts/gitea-bundle-mirror.sh` auf Frische und Bundle-Klonbarkeit pruefen, Secrets-Inventur gegen `docs/SECRETS_MAP.md` abgleichen.
|
||||
|
||||
### Wer schiebt das an?
|
||||
|
||||
- **Operator** loest jeden Drill manuell aus, idealerweise am 2. Wochenende des ersten Monats im Quartal.
|
||||
- Es gibt **keinen** automatischen Host-Schedule fuer den Quartals-Drill. Die woechentliche Freshness-Pruefung und die monatlichen Mini-Restores in `ops/restore-tests/schedule.md` laufen separat.
|
||||
- Bei akuten Aenderungen (Major-Upgrade eines Dienstes, FS-Migration, Repo-Strukturaenderung): zusaetzlichen Ad-hoc-Drill ausserhalb der Quartals-Kadenz einplanen.
|
||||
|
||||
## Freshness-Check (woechentlich)
|
||||
|
||||
- Skript: `ops/restore-tests/check-restore-freshness.sh` (Host-Bash) bzw. `ops/restore-tests/check-restore-freshness.ps1` (Windows-Operator).
|
||||
- Erwartete Pruefungen:
|
||||
- Letzter Borg-Archiv-Stand juenger als die Schwellwerte aus `docs/STORAGE_LAYOUT.md` §11.
|
||||
- Kanonische Dump-Artefakte unter `/mnt/user/backups/borg/dumps/latest/` vorhanden und juenger als 26 h.
|
||||
- Letzte Report-Dateien unter `/mnt/user/backups/restore-reports/` lesbar.
|
||||
- Gitea-Bundles unter `/mnt/user/backups/git-bundles/gitea/` plausibel aktuell.
|
||||
|
||||
Ergebnis ist ein kurzes Konsolen-Log; bei Fehler greift die ntfy-Alarmierung aus `docs/ALERTING_MAP.md`.
|
||||
|
||||
## Mini-Restore (monatlich / bimonatlich)
|
||||
|
||||
Skripte folgen alle demselben Muster:
|
||||
|
||||
- isoliertes Test-Lab unter `/mnt/user/backups/restore-lab/<dienst>`
|
||||
- isolierte Test-Container `restoretest-*`
|
||||
- nur `127.0.0.1`-Ports, keine Traefik-Labels, keine produktive Domain
|
||||
- Smoke-Test mit Erfolgsregel "Container laeuft reicht nicht"
|
||||
- Report unter `/mnt/user/backups/restore-reports/<dienst>-YYYY-MM-DD.md`
|
||||
|
||||
Operative Anleitungen je Dienst:
|
||||
|
||||
- `ops/restore-tests/vaultwarden-runbook.md`
|
||||
- `ops/restore-tests/gitea-runbook.md`
|
||||
- `ops/restore-tests/paperless-runbook.md`
|
||||
- `ops/restore-tests/immich-runbook.md`
|
||||
|
||||
## DR-Sanity-Check (quartalsweise)
|
||||
|
||||
Der Sanity-Check ist **kein** echter Restore. Er ist eine Doku-/Konsistenz-Pruefung mit zehn Punkten:
|
||||
|
||||
1. `docs/DISASTER_RECOVERY.md` Phase 1-5 noch konsistent mit Repo und Live-Stand?
|
||||
2. `docs/RESTORE_MATRIX.md` Tier-Klassifizierung pro Dienst aktuell?
|
||||
3. `docs/SECRETS_MAP.md` Pfade existieren, Stack-ENV-only-Liste aktuell?
|
||||
4. `docs/SERVICES_RECOVERY.md` Komodo-Bootstrap-Pfad noch in Stufen A-F konsistent?
|
||||
5. Gitea-Bundle-Mechanik laeuft und letzter Bundle-Stand klonbar (`git clone .../homelab-infra.bundle /tmp/restore-test`)?
|
||||
6. Externe Mirrors (`michaelkaleschke-spec/homelab-infra` auf GitHub) gemaess `docs/EXTERNAL_DEPENDENCIES.md` noch erreichbar und aktuell?
|
||||
7. ntfy-Push-Pfad noch erreichbar? (Test-Nachricht an `homelab-info`.)
|
||||
8. Letzte vier Quartals-Mini-Restores im Report-Verzeichnis vorhanden?
|
||||
9. Borg-Repo-Passphrase Offline-Sicherung noch auffindbar? (Pruefung durch Operator, nicht durch Skript, kein Wert ablegen.)
|
||||
10. Capacity-Stand gegen Schwellen aus `docs/CAPACITY_AND_LIFECYCLE.md` abgeglichen?
|
||||
|
||||
Jeder Punkt wird in einem kurzen Quartals-Eintrag in `docs/MIGRATION_LOG.md` als `ok` / `Abweichung` / `Folgeaufgabe` festgehalten.
|
||||
|
||||
## Abbruch-Regeln
|
||||
|
||||
Wenn ein Drill fehlschlaegt, gilt die Stop-Regel aus `docs/WORKFLOW.md`:
|
||||
|
||||
- nach zwei fehlgeschlagenen Reparaturversuchen nicht weiterschreiben
|
||||
- stattdessen Pflichtmatrix aus `docs/GITOPS_DRIFT_RUNBOOK.md` durchgehen
|
||||
- Befund dokumentieren, naechsten Schritt mit dem Operator klaeren
|
||||
- erst danach den Drill erneut starten oder das Quartal als "Drill incomplete" markieren
|
||||
|
||||
## Berichte
|
||||
|
||||
- Mini-Restore-Reports liegen unter `/mnt/user/backups/restore-reports/<dienst>-YYYY-MM-DD.md`.
|
||||
- Quartals-Sanity-Checks landen als kurzer Block in `docs/MIGRATION_LOG.md`, nicht als eigenes Dokument.
|
||||
- Reports werden nicht aus dem Repo verlinkt, weil sie nicht im Repo liegen. Operator dokumentiert nur Vorhanden/Erfolg/Datum.
|
||||
|
||||
## Geltungsdauer
|
||||
|
||||
Diese Routine gilt ab Q2 2026. Bei groesseren Aenderungen (zweites Off-site, Authelia-OIDC-Aktivierung, Hardware-Migration) wird die Liste pro Quartal angepasst.
|
||||
+114
-14
@@ -47,30 +47,128 @@ git -C /tmp/repo-restore-test fsck
|
||||
|
||||
## Komodo Bootstrap
|
||||
|
||||
Problem: Komodo verwaltet Stacks, ist aber selbst Teil des Recovery-Pfads. Ein kalter Host darf nicht voraussetzen, dass Komodo schon laeuft.
|
||||
### Problemstellung
|
||||
|
||||
Komodo ist deshalb bewusst kein normaler Auto-Deploy-Stack: der `komodo`-Self-Stack hat keinen aktiven Gitea-Webhook. Recovery und Aenderungen laufen ueber den dokumentierten Bootstrap-Pfad und muessen nach dem Start in Komodo validiert werden.
|
||||
Komodo verwaltet alle Stacks per GitOps, ist aber selbst Teil des Recovery-Pfads. Ein kalter Host darf **nicht** voraussetzen, dass Komodo schon laeuft. Das ist das klassische Henne-Ei-Problem: Komodo darf sich nicht selbst aus dem Repo holen muessen, bevor es laufen kann.
|
||||
|
||||
Minimaler Wiederanlauf:
|
||||
### Recovery-Anker (verbindlich)
|
||||
|
||||
1. Docker und externe Netze herstellen (`frontend_net`, `backend_net`, ggf. weitere dokumentierte Netze).
|
||||
2. Repo aus Gitea/GitHub Mirror klonen.
|
||||
3. Komodo Compose aus `ops/komodo/docker-compose.yml` oder einem spaeteren Bootstrap-Pfad starten.
|
||||
4. Erforderliche `.env`/Secrets aus Host-Secret-Backup wiederherstellen.
|
||||
5. Komodo-Core, Periphery und Mongo starten.
|
||||
6. Web-UI und Periphery-Verbindung pruefen.
|
||||
**Anker:** `ops/komodo/docker-compose.yml` aus dem Repo.
|
||||
|
||||
Offene Aufgabe:
|
||||
Dieses Compose-File ist die einzige Quelle, aus der Komodo nach einem Kaltstart hochgefahren wird. Es wird nicht ueber Komodos eigenen Auto-Deploy-Pfad konsumiert.
|
||||
|
||||
- Entscheidung 2026-05-26: `ops/komodo/docker-compose.yml` bleibt die verbindliche Bootstrap-Quelle. Der `komodo`-Self-Stack hat keinen aktiven Gitea-Webhook und ist nicht der Recovery-Anker.
|
||||
- Offen bleibt nur ein spaeterer Trockenlauf, bei dem die Komodo-Startkommandos gegen echte Restore-Pfade getestet werden.
|
||||
**Was der Anker bewusst NICHT ist:**
|
||||
|
||||
Validierung:
|
||||
- nicht der Komodo-Self-Stack (Komodo darf sich nicht selbst deployen).
|
||||
- nicht der laufende Komodo-Workspace unter `/mnt/user/services/stacks/komodo/compose.yaml` (kann driften, siehe `HOMELAB_ARCHITECTURE_MASTER_V2.md` Sektion 13, Drift-Recovery 2026-05-04).
|
||||
- nicht ein Gitea-Webhook (`komodo`-Stack hat bewusst `webhook_enabled: false`).
|
||||
|
||||
**Quelle der Compose-Datei:**
|
||||
|
||||
1. Vorzug: lokaler Repo-Clone auf dem Operator-Windows-PC (`G:\Gitea_Clone\homelab-infra\`).
|
||||
2. Fallback: GitHub-Mirror `michaelkaleschke-spec/homelab-infra` (siehe `docs/EXTERNAL_DEPENDENCIES.md`).
|
||||
3. Letzter Fallback: Gitea-Bundles unter `/mnt/user/backups/git-bundles/gitea/homelab-infra.bundle` (siehe Mirror-Abschnitt oben).
|
||||
|
||||
Wenn alle drei Quellen down sind, ist Recovery blockiert und das Problem ist nicht Komodo, sondern Repo-Verlust.
|
||||
|
||||
### Kaltstart-Schritte
|
||||
|
||||
Der Wiederanlauf-Pfad ist linear; jeder Schritt hat ein eindeutiges Erfolgskriterium, bevor der naechste laeuft.
|
||||
|
||||
**Stufe A - Host und Docker-Grundlage**
|
||||
|
||||
1. Unraid bootet; Array ist online; Shares `/mnt/user/appdata`, `/mnt/user/services`, `/mnt/user/backups` sichtbar.
|
||||
2. Docker-Daemon laeuft (`docker info` antwortet).
|
||||
3. Externe Docker-Netze existieren oder werden erzeugt (`frontend_net`, `backend_net`). Wenn nicht vorhanden: `docker network create --driver bridge frontend_net` bzw. `... --internal backend_net`.
|
||||
|
||||
Erfolgskriterium: `docker network ls` zeigt `frontend_net` und `backend_net`.
|
||||
|
||||
**Stufe B - Repo-Quelle bereitstellen**
|
||||
|
||||
1. Repo-Clone aus dem bevorzugten Pfad bereithalten:
|
||||
- lokaler Operator-Clone, oder
|
||||
- frischer Clone aus GitHub-Mirror, oder
|
||||
- Bundle-Restore aus `/mnt/user/backups/git-bundles/gitea/homelab-infra.bundle` (`git clone homelab-infra.bundle homelab-infra`).
|
||||
2. Repo-Stand verifizieren: `git -C <pfad> log --oneline -1` zeigt einen plausibel aktuellen Commit.
|
||||
|
||||
Erfolgskriterium: `ops/komodo/docker-compose.yml` ist auf dem Host lesbar.
|
||||
|
||||
**Stufe C - Komodo-Secrets bereitstellen**
|
||||
|
||||
Komodo braucht beim Start mehrere Secrets, die **nicht** aus dem Repo kommen. Restore-Reihenfolge gemaess `docs/SECRETS_MAP.md`:
|
||||
|
||||
1. Host-Secrets unter `/mnt/user/appdata/secrets/` wiederherstellen (aus Borg oder analog gesicherter Quelle).
|
||||
2. Datei `/mnt/user/appdata/secrets/komodo_mongo_password.txt` ist Pflicht (Mongo-Initialisierung).
|
||||
3. Stack-ENV-Werte `KOMODO_SECRET_KEY`, `KOMODO_WEBHOOK_SECRET`, `KOMODO_JWT_SECRET`, `KOMODO_MONGO_PASSWORD`, `KOMODO_PERIPHERY_PASSKEY` muessen als Host-`.env` neben dem Compose vorliegen. Quelle in dieser Reihenfolge: Vaultwarden (sobald restauriert), externe Operator-Notiz, oder Komodo-Mongo-Dump (nur wenn Mongo separat bereits gestartet und die `stack`-Collection lesbar ist).
|
||||
|
||||
Erfolgskriterium: Compose-Validierung laeuft ohne fehlende Variablen.
|
||||
|
||||
```bash
|
||||
docker compose -f ops/komodo/docker-compose.yml config >/dev/null
|
||||
```
|
||||
|
||||
**Stufe D - Komodo starten**
|
||||
|
||||
1. Compose hochfahren:
|
||||
|
||||
```bash
|
||||
docker compose -f ops/komodo/docker-compose.yml config
|
||||
docker compose -f ops/komodo/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
2. Reihenfolge intern: `komodo-mongo` zuerst healthy, dann `komodo-core`, dann `komodo-periphery`.
|
||||
3. Status pruefen:
|
||||
|
||||
```bash
|
||||
docker ps --filter "name=komodo"
|
||||
docker logs --tail 50 komodo-core
|
||||
docker logs --tail 50 komodo-periphery
|
||||
```
|
||||
|
||||
Erfolgskriterium: alle drei Container laufen; Komodo-Core meldet Bind auf Port `9120`; Periphery meldet erfolgreiche Verbindung zu Core.
|
||||
|
||||
**Stufe E - Web-UI und GitOps validieren**
|
||||
|
||||
1. `https://komodo.kaleschke.info` ist erreichbar (Authelia-Bypass dokumentiert, native Komodo-Auth aktiv).
|
||||
2. Komodo zeigt im Web-UI die bekannten Stacks aus Gitea (sobald Gitea ebenfalls laeuft; siehe `docs/DISASTER_RECOVERY.md` Phase 4 Stufe 2 vor Stufe 3).
|
||||
3. Gitea-Webhooks gegen Komodo werden separat in der Phase-4-Reihenfolge geprueft, **nicht** als Teil des Komodo-Bootstraps.
|
||||
|
||||
Erfolgskriterium: Komodo-UI laedt, Periphery `Online`, mindestens ein Stack aus Gitea sichtbar.
|
||||
|
||||
**Stufe F - Stacks in Tier-Reihenfolge aufnehmen**
|
||||
|
||||
Erst nach erfolgreichem Komodo-Bootstrap werden produktive Stacks ueber den dokumentierten Stufenpfad in `docs/DISASTER_RECOVERY.md` Phase 4 hochgefahren (Traefik, AdGuard, Tailscale, dann PostgreSQL, Authelia, Redis, Gitea, dann Apps).
|
||||
|
||||
### Trockenlauf-Idee (Doku-only, nicht ausgefuehrt)
|
||||
|
||||
Ein bewusster Trockenlauf des Komodo-Bootstraps gegen Wegwerf-Pfade ist die naechste sinnvolle Reife-Stufe. Vorschlag:
|
||||
|
||||
| Schritt | Inhalt |
|
||||
|---|---|
|
||||
| 1 | Test-Compose aus `ops/komodo/docker-compose.yml` in `/mnt/user/backups/restore-lab/komodo/` kopieren |
|
||||
| 2 | Test-`.env` mit Wegwerf-Secrets erzeugen (nicht produktive Werte!) |
|
||||
| 3 | `docker compose -f .../restore-lab/komodo/docker-compose.yml -p restoretest-komodo up -d` |
|
||||
| 4 | Smoke: Mongo healthy, Core antwortet auf `http://127.0.0.1:<test-port>/api/health`, Periphery verbindet |
|
||||
| 5 | `docker compose -p restoretest-komodo down -v` und Restore-Lab bereinigen |
|
||||
|
||||
Der Trockenlauf ist **noch nicht** als Repo-Skript abgelegt. Er bleibt als Folgeschritt analog zum Immich-Restore-Test geplant.
|
||||
|
||||
### Validierungs-Kommandos (Snapshot)
|
||||
|
||||
```bash
|
||||
# Compose syntaktisch ok?
|
||||
docker compose -f ops/komodo/docker-compose.yml config >/dev/null
|
||||
|
||||
# Komodo-Container vorhanden und laufend?
|
||||
docker ps --filter "name=komodo" --format "table {{.Names}}\t{{.Status}}"
|
||||
|
||||
# Mongo Health?
|
||||
docker exec komodo-mongo mongosh --quiet --eval 'db.adminCommand({ping:1}).ok'
|
||||
|
||||
# Core API up?
|
||||
docker exec komodo-core sh -lc 'wget -q -O- http://127.0.0.1:9120/api/health || true'
|
||||
|
||||
# Periphery sichtbar?
|
||||
docker logs --tail 50 komodo-periphery 2>&1 | grep -i "connected\|periphery"
|
||||
```
|
||||
|
||||
## Secrets Recovery Reihenfolge
|
||||
@@ -98,5 +196,7 @@ Authoritativ ist `docs/SECRETS_MAP.md`. Fuer den Kaltstart ist diese Reihenfolge
|
||||
|---|---|
|
||||
| erledigt (Skript + Host-Test) | Gitea-Bundle- oder Mirror-Mechanik final entscheiden |
|
||||
| erledigt | Komodo-Bootstrap-Quelle finalisieren |
|
||||
| erledigt (Doku) | Komodo-Kaltstart in linearen Stufen A-F dokumentieren |
|
||||
| offen | Komodo-Trockenlauf-Skript in `ops/restore-tests/` analog zu Immich vorbereiten |
|
||||
| offen | Restore-Kommandos nach erstem Trockenlauf mit echten Pfaden ergaenzen |
|
||||
| erledigt | Services-Recovery in `docs/DISASTER_RECOVERY.md` verlinken |
|
||||
|
||||
@@ -26,14 +26,16 @@ Alle 2 Monate:
|
||||
|
||||
Quartalsweise:
|
||||
|
||||
- Restore-/DR-Sanity-Check
|
||||
- `immich` Restore-Smoke-Test (DB + UI, ohne produktive Foto-Mounts)
|
||||
- Restore-/DR-Sanity-Check gemaess `docs/RESTORE_DRILL_ROUTINE.md`
|
||||
- `immich` Restore-Smoke-Test (DB + UI, ohne produktive Foto-Mounts; Erstlauf 2026-05-27 erfolgreich)
|
||||
- pruefen:
|
||||
- Restore-Lab-Struktur
|
||||
- Reports
|
||||
- Skripte und Pfade
|
||||
- Doku noch passend
|
||||
|
||||
Die Quartals-Belegung (welcher Dienst, welcher Sanity-Fokus) steht in `docs/RESTORE_DRILL_ROUTINE.md` Tabelle "Quartals-Kadenz".
|
||||
|
||||
## Konkreter Kalender
|
||||
|
||||
- Jeden Montag, 06:30:
|
||||
|
||||
Reference in New Issue
Block a user