From 513f41b852033d744f12ec35485664c553150635 Mon Sep 17 00:00:00 2001 From: Micha Date: Thu, 11 Jun 2026 07:06:18 +0200 Subject: [PATCH] docs: introduce DECISIONS.md decision register, slim architecture master - new docs/DECISIONS.md (ADR-light): decisions migrated from master section 13, MASTER_TODO parked items, hardware inventory and audit restliste into one chronological register - HOMELAB_ARCHITECTURE_MASTER_V2.md: section 13 replaced by pointer, section 9 condensed (502 -> 372 lines, target picture only) - ROLLBACK.md: drop rollback recipes for already removed services (uptime-kuma, grafana/influx legacy, stirling/glance bootstrap notes) Co-Authored-By: Claude Fable 5 --- HOMELAB_ARCHITECTURE_MASTER_V2.md | 195 ++---------------------------- docs/DECISIONS.md | 118 ++++++++++++++++++ docs/ROLLBACK.md | 77 +++--------- 3 files changed, 141 insertions(+), 249 deletions(-) create mode 100644 docs/DECISIONS.md diff --git a/HOMELAB_ARCHITECTURE_MASTER_V2.md b/HOMELAB_ARCHITECTURE_MASTER_V2.md index c4cf400..a1b7521 100644 --- a/HOMELAB_ARCHITECTURE_MASTER_V2.md +++ b/HOMELAB_ARCHITECTURE_MASTER_V2.md @@ -3,7 +3,7 @@ > **Single Source of Truth** für Docker-Netzwerkarchitektur, Sicherheitsregeln, Zielbild und Migration des Kallilabcore-Homelabs. > **Arbeitsregel für KI-Assistenten:** Dieses Dokument immer zuerst lesen, bevor Fragen zu Containern, Netzwerken, Traefik, Tailscale, Migration oder Security beantwortet werden. -**Stand:** 2026-06-02 | **Aktueller Schwerpunkt:** GitOps / Doku-Synchronisierung / Reproduzierbare Deployments +**Stand:** 2026-06-11 | **Aktueller Schwerpunkt:** GitOps / Doku-Synchronisierung / Reproduzierbare Deployments --- @@ -20,7 +20,7 @@ 10. [Bekannte Ausnahmen und Begründungen](#10-bekannte-ausnahmen-und-begründungen) 11. [Projektorganisation und Arbeitsmodus](#11-projektorganisation-und-arbeitsmodus) 12. [Nutzung mit KI / Kontext-Regel](#12-nutzung-mit-ki--kontext-regel) -13. [Betriebserfahrungen und Entscheidungs-Log](#13-betriebserfahrungen-und-entscheidungs-log) +13. [Betriebserfahrungen und Entscheidungs-Log (ausgelagert)](#13-betriebserfahrungen-und-entscheidungs-log-ausgelagert) --- @@ -371,23 +371,7 @@ labels: ## 9. Historische Migration (abgeschlossen) -Die frühere Blockmigration aus der Portainer-/Dockerman-Phase ist fachlich abgeschlossen. - -Dieser Abschnitt dient nur noch als **historischer Vermerk**: - -- Traefik läuft labelbasiert ohne Service-Routen im File-Provider. -- Komodo ist der einzige aktive Stack-Manager. -- Portainer CE ist entfernt. -- Borg/Borg UI, Dump-Automatisierung und Restore-Test sind produktiv eingeführt. -- Frühere Sprint-/Block-Checklisten werden hier **nicht mehr operativ gepflegt**. - -Für den laufenden Betrieb gilt stattdessen: - -- Zielbild und Architektur in diesem Dokument -- Git-/Komodo-Ablauf in `docs/WORKFLOW.md` -- fachliche Änderungen in der jeweils betroffenen Stack-Doku -- Entscheidungen und besondere Umstellungen im Entscheidungs-Log unten - +Die Blockmigration aus der Portainer-/Dockerman-Phase ist abgeschlossen: Traefik laeuft labelbasiert ohne File-Provider-Service-Routen, Komodo ist alleiniger Stack-Manager, Portainer CE ist entfernt, Borg/Dumps/Restore-Tests sind produktiv. Entscheidungen und Hintergruende stehen in `docs/DECISIONS.md`; die Sprint-Historie liegt in Git. ## 10. Bekannte Ausnahmen und Begründungen | Container | Ausnahme | Begründung | @@ -464,176 +448,15 @@ Damit ist sofort klar: --- -## 13. Betriebserfahrungen und Entscheidungs-Log +## 13. Betriebserfahrungen und Entscheidungs-Log (ausgelagert) -### Fix Common Problems Plugin entfernt (2026-06-03) - -Befund: Drei `grep -R ... /usr/local/emhttp`-Prozesse liefen seit ~7 Tagen durchgehend mit je 100 % CPU (TIME+ 177-179 h). Status `R`, von PID 1 adoptierte Zombies einer laengst beendeten Fix-Common-Problems-(FCP)-Scan-Session. Folge: konstante Load 14.6 auf 12 Cores, IOWAIT-Peaks bis 55 %, USB-Flash unter Dauer-IO. - -Ursache: Unraids `/usr/local/emhttp` enthaelt Symlinks `mnt -> /mnt` (mehrere TB Array) und `boot -> /boot` (USB-Flash). GNU `grep -R` dereferenziert Symlinks rekursiv. Ein FCP-Scan-Schritt (`/etc/cron.daily/fix.common.problems.sh -> scripts/scan.php`) hat dadurch effektiv die gesamte Array-Struktur gegrept und ist beim ersten Treffer-Loop haengen geblieben. Der Lock `/tmp/fix.common.problems/scanRunning` war vom 2026-06-03 04:40 - jeder weitere Daily-Cron-Run wuerde dasselbe Verhalten reproduzieren. - -Massnahme: FCP-Plugin per `plugin remove fix.common.problems.plg` deinstalliert. Cron-Eintrag, Plugin-Verzeichnis und `/tmp`-Reste sauber. Load fiel innerhalb Minuten auf 1.08 (1-min). - -Entscheidung: FCP wird bewusst **nicht** wieder installiert. Begruendung: - -- Restliche Risiken werden bereits ueber andere Wege abgedeckt: Scrutiny (Laufwerks-SMART), Monitoring-Stack (Container-Health, Prometheus-Alerts, Blackbox), Posture-Check (Filesystem-/Drift-/Authelia-Audit), Critical-Events-Watcher (`services/posture-check/docker-critical-events.sh`). -- FCP ist ein externes Community-Plugin und nicht Teil der Repo-managed GitOps-Welt; Verhalten haengt von einer Online-Templates-Datei ab. -- Ein einmaliges Hang-up reicht, um die Flash-Drive 7 Tage lang zu thrashen - das Verhaeltnis Nutzen/Risiko ist negativ. - -Folgen fuer Doku: Eintrag in `docs/AUDIT_2026-05-25_TODO.md` unter "Zuletzt geschlossen"; FCP taucht nicht mehr als Voraussetzung in DR/Monitoring-Pfaden auf, da es nie produktiv referenziert war. - -### Plex Server Reclaim und LAN-only-Profil (2026-05-28) - -Befund: Die `Preferences.xml` des Plex-Servers war seit dem 18.05.2026 13:18 jungfraeulich (391 Bytes, ohne `PlexOnlineMail`/`PlexOnlineUsername`/`PlexOnlineToken`). Der Server war damit nicht mit einem Plex.tv-Account geclaimt, obwohl die Smart-TVs ueber LAN-Discovery (mDNS/Plex-GDM) weiter funktionierten. Beim Login als `Xeridos` ueber `app.plex.tv` meldete der Server "Keine Berechtigung", weil kein Owner registriert war. Zusaetzlich war die `library_sections`-Konfiguration leer (Backups vom 19./22./28.05. ebenfalls ~370 KB statt MBs/GBs); die Bibliotheks-Konfiguration war seit dem 18.05. weg, die Filmdateien unter `/mnt/user/media/*` blieben aber intakt (~833 Verzeichnisse, davon `movies/` 1.4 TB und `Heimatfilme/` 300 GB). - -Reclaim: - -- Operator-Claim-Token via `https://www.plex.tv/claim` als `Xeridos` erzeugt. -- Plex-Container per `PLEX_CLAIM=claim-... docker compose up -d --force-recreate plex` am Host-Pfad `/mnt/user/services/stacks/plex/host-services/plex` neu erstellt. Token wurde **nur** als Shell-Inline-ENV mitgegeben, **nicht** in eine `.env`-Datei, **nicht** in die Compose, **nicht** in die Komodo-Stack-ENV geschrieben. -- Nach Erfolg: zweiter `docker compose up -d --force-recreate plex` ohne `PLEX_CLAIM`, damit der verbrauchte Token nicht im `docker inspect`-ENV-Snapshot persistiert. -- Bash-History defensiv geleert. - -Endstand: - -- `PlexOnlineUsername="Xeridos"`, `PlexOnlineMail="michideheld@gmx.de"`, `PlexOnlineHome="1"`. -- Bibliotheken neu angelegt via Plex-Web → Verwalte Mediatheken → `/data/movies`, `/data/Heimatfilme` etc. -- `PublishServerOnPlexOnlineKey="0"` (Remote Access deaktiviert), Plex-Relay aus. -- 2026-06-06: Externer Komfortzugriff ueber `https://plex.kaleschke.info` via Traefik ergaenzt. Das ist **kein** Plex-Remote-Access und keine direkte FRITZ!Box-Freigabe auf `32400`; Plex bleibt hinter Traefik/443 und nutzt native Plex-Auth. - -Konsequenzen fuer Doku/Betrieb: - -- Plex-Home-Familien-Profil ("Familie") muss bei Bedarf neu eingeladen werden; war ohnehin nicht aktiv genutzt. -- Watch-State aus der Zeit vor dem 18.05. ist nicht recoverbar; Filme/Serien laufen bei Wiederaufruf bei 00:00 los. -- `host-services/plex/docker-compose.yml` enthaelt weiter `PLEX_CLAIM: ${PLEX_CLAIM:-}`, damit ein zukuenftiger Reclaim ohne Repo-Aenderung moeglich ist. - -### Traefik — Wechsel zu reinen Docker-Labels (2026-03-28) -Die statischen File-Provider-Konfigurationen in `/mnt/user/appdata/traefik/dynamic/` wurden vollständig bereinigt: -- **Gelöscht:** `immich.yml`, `gitea.yml`, `mealie.yml`, `scrutiny.yml`, `vaultwarden.yml.bak` -- **Verbleibend (notwendig):** `middlewares.yml`, `tls.yml`, `dashboards.yml` - -**Hintergrund:** Die alten File-Provider-Configs haben `@file`-Routen mit `@docker`-Routen konkurrieren lassen. In Traefik v3 gewinnt der File-Provider und hat z.B. Immich auf die falsche IP geroutet (Bad Gateway). Nach Löschung läuft Traefik ausschließlich auf Docker-Labels. - -**Regel:** Neue Dienste ausschließlich via Docker Compose Labels konfigurieren. Keine neuen `.yml`-Dateien im `dynamic/`-Verzeichnis für Service-Routen anlegen. - -### Komodo — Ablösung von Portainer als Stack-Manager (2026-03-28) -Komodo ist nun der primäre GitOps-Stack-Manager: -- **Komodo Core** läuft als Docker-Stack (`ops/komodo/docker-compose.yml`) -- **Komodo Periphery** läuft auf dem Unraid-Host für direktes Server-Management -- Stacks werden via Gitea synchronisiert und über Komodo deployed -- Portainer CE ist abgeschaltet; Komodo ist der alleinige aktive Stack-Manager - -**Betriebsregel:** Alle Stack-Änderungen laufen über Git; Komodo konsumiert nur den Stand aus Gitea. - -**Zugangsregel:** Komodo bleibt bewusst bei nativer Authentifizierung ohne pauschal vorgeschaltete ForwardAuth-Middleware vor dem gesamten Router. Hintergrund sind die gemischten UI-, API-, Webhook- und Periphery-Endpunkte unter derselben Domain. - -### Komodo Self-Stack Drift-Recovery (2026-05-04) -- Befund: `komodo-core` und `komodo-periphery` liefen aus temporaeren `/tmp/*repair.yml`-Dateien, waehrend `komodo-mongo` auf den fehlenden persistenten Pfad `/mnt/user/services/stacks/komodo/compose.yaml` verwies. -- Recovery: Repair-YAMLs und Runtime-ENV wurden unter `/mnt/user/appdata/komodo/_drift_backup_2026-05-04/` gesichert; eine zusaetzliche Recovery-ENV liegt unter `/mnt/user/appdata/secrets/_komodo_stack_env_recovery_2026-05-04.env` und ist als temporaeres Tier-1-Secret-Material zu behandeln. -- Der persistente Self-Stack wurde unter `/mnt/user/services/stacks/komodo/compose.yaml` aus `ops/komodo/docker-compose.yml` wiederhergestellt. Die hostseitige `.env` bleibt ausserhalb von Git. -- Reconcile-Regel: Bei Self-Stack-Drift keinen pauschalen `docker compose up -d` ausfuehren, wenn der Dry-run `komodo-mongo` recreaten wuerde. Core und Periphery koennen gezielt mit `--no-deps` neu erstellt werden, Mongo bleibt dabei unangetastet. -- Ergebnis: Alle drei Komodo-Container zeigen wieder auf `/mnt/user/services/stacks/komodo/compose.yaml`; Mongo blieb waehrend der Rueckfuehrung healthy. - -### AdGuard Home — Ablösung von Pi-hole (2026-03-28) -`binhex-official-pihole` wurde entfernt und durch `AdGuard Home` + `unbound` ersetzt: -- AdGuard läuft als Git-Stack (`host-services/Adguard/docker-compose.yml`) -- Netzwerke: `dns_net` (feste IP 172.23.0.3) + `frontend_net` -- Port 53 (DNS) direkt gebunden — dokumentierte Ausnahme -- Admin-UI direkt gebunden via Tailscale-IP `100.80.98.33:8082` auf Container-Port 80 — 2026-05-26 bewusst als einfache Operator-Entscheidung ohne Traefik-/2FA-Umstellung -- `unbound` läuft weiterhin als Upstream-Resolver in `dns_net` - -### diun — Entfernung (2026-03-28) -`diun` (Docker Image Update Notifier) wurde deinstalliert: -- Stack gelöscht -- Orphan-Netzwerk `diun_diun_default` bereinigt -- Repo-Eintrag `infra/diun/` aus Git entfernt - -Update-Monitoring kann über Komodo's eingebaute Update-Notifications abgedeckt werden. - -### ntfy — Push-Notifications (Git-Stack) -`ntfy` läuft als Git-Stack (`apps/ntfy/docker-compose.yml`): -- `ntfy.kaleschke.info` via Traefik -- `NTFY_UPSTREAM_BASE_URL: https://ntfy.sh` für mobile Push-Notifications -- `NTFY_BEHIND_PROXY: true` korrekt gesetzt - -### immich_default — internal: true gesetzt (2026-03-29) -`immich_default` wurde von `external: true` auf ein Compose-verwaltetes internes Netz umgestellt: -- **Vorher:** `external: true` (manuell erstellt, falsche Labels `com.docker.compose.network=default`) -- **Nachher:** Compose-managed, `internal: true`, `driver: bridge`, korrekte Labels -- Durchgeführt via: manuelles `docker stop` der Containers → `docker network rm immich_default` → Komodo Redeploy -- Ergebnis: alle Immich-Container (`immich_postgres`, `immich_redis`, `immich_machine_learning`) sind jetzt vom Internet isoliert; nur `immich_server` hat zusätzlich `frontend_net` für Traefik - -### Secrets in Komodo Stacks -Host-Pfade in `env_file` (z.B. `/mnt/...`) sind in Git-Stacks nicht verfügbar. Standardlösung: Stack Environment Variables + `${VARIABLE_NAME}` in der Compose. - -**Regel:** Wenn `_FILE` nicht unterstützt wird → Stack Environment Variable. Kein Secret im Git. - -**Bewusste Ausnahme:** `paperless-ngx` bleibt fuer `PAPERLESS_DBPASS` und `PAPERLESS_REDIS` vorerst bei Stack Environment Variables. Eine Umstellung auf `_FILE` ist fachlich denkbar, wird aber nicht gegen den aktuell stabilen Produktionsstand erzwungen. - -### Borg UI / BorgBase (2026-04-12) -- `borg-ui` läuft als Admin-Dienst in `ops/borg-ui/docker-compose.yml` -- nur `frontend_net`, weil Web-UI + externer SSH-Zugang zu BorgBase benötigt werden -- keine direkten Host-Ports; Zugriff ausschließlich via Traefik + Middleware über `borg.kaleschke.info` -- breite Restore-/Backup-Mounts bewusst gesetzt; inklusive `/local/secrets` fuer Disaster Recovery, separates Restore-Ziel unter `/mnt/user/appdata/borg-ui/restore` -- kein separater Borg-CLI-Container nötig, da Borg UI die Borg-CLI bereits im Container mitbringt - -| Container | `_FILE` Support | -|---|---| -| Vaultwarden | ✅ ja | -| PostgreSQL | ✅ ja | -| code-server | ✅ ja (`PASSWORD_FILE`) | -| Immich Postgres | ✅ ja (`POSTGRES_PASSWORD_FILE`) | -| Mealie | ✅ ja (`POSTGRES_PASSWORD_FILE`) | -| paperless-ngx | ❌ nein für DB-Pass → Stack ENV | - -### Reproduzierbare Deployments (2026-04-17) -Mutable Tags wie `latest`, `stable`, `release` oder reine Major-Tags wurden auf die **aktuell laufenden Digests** eingefroren. Das ist bewusst **kein Upgrade-Mechanismus**, sondern dient dazu, den heute funktionierenden Laufzeitstand exakt im Repo festzuhalten. Echte Versions-Upgrades bleiben ein eigener, geplanter Schritt. - -### Stateful Digest-Pinning (2026-05-05, ergaenzt 2026-05-16) -- Tier-1/stateful Basisdienste werden bevorzugt mit sprechendem Minor-/Patch-Tag plus Digest gepinnt, z. B. `postgres:17.9@sha256:...` oder `mongo:7.0.32@sha256:...`. -- Redis-Caches sind seit dem Hardening-Sprint 2026-05-16 auf `redis:7.4-alpine@sha256:...` vereinheitlicht. Updates erfolgen bewusst stackweise mit Smoke-Test. -- Bereits versionierte Apps koennen optional spaeter ebenfalls Digests erhalten; dieser Schritt ist getrennt vom Datenhalter-Pinning. - -### Nextcloud und Stirling-PDF (2026-04-19) -- `nextcloud` wird bewusst **nicht** als AIO-Stack gebaut, sondern als klassischer Docker-Microservice-Stack mit eigenem PostgreSQL und eigenem Redis. Das passt besser zum bestehenden GitOps-/Compose-Modell des Repos. -- `nextcloud` bleibt bei nativer App-Authentifizierung ohne zentrale ForwardAuth-Middleware vor dem Router, damit Browser-Login, Desktop-/Mobile-Clients sowie WebDAV/CardDAV sauber funktionieren. -- `stirling-pdf` wird als geschuetzter Tool-Stack hinter `authelia@file,secure-headers@file` betrieben; die interne Stirling-Login-Funktion bleibt deaktiviert, um Doppel-Login zu vermeiden. - -### BentoPDF und Monitoring-Zielstack (2026-04-30, aktualisiert 2026-05-17) -- `bentopdf` ersetzt repo-seitig `stirling-pdf` auf der bestehenden Domain `pdf.kaleschke.info`, bleibt aber bis zum bewussten Komodo-Deploy nur vorbereitet. -- BentoPDF benoetigt fuer Office-Konvertierung die Cross-Origin-Isolation-Header `Cross-Origin-Opener-Policy: same-origin` und `Cross-Origin-Embedder-Policy: require-corp`; diese werden per Traefik-Docker-Middleware gesetzt. -- `monitoring/` ist der zentrale Zielstack fuer Prometheus, Loki, Promtail, Grafana, node-exporter, cAdvisor und InfluxDB 3 Core. -- `monitoring-grafana` wird als geschuetztes Monitoring-UI unter `monitoring.kaleschke.info` betrieben. -- `monitoring-influxdb3-core` bleibt ohne Traefik-/Public-Route; fuer interne Writer wie Home Assistant kann Port `8181` per `INFLUXDB_BIND_IP` auf eine LAN-Adresse gebunden werden. -- Fuer dieses Port-Publishing nutzt `monitoring-influxdb3-core` zusaetzlich `monitoring_influx_lan`. Das ist keine Public-App-Freigabe und ersetzt nicht die Token-Authentifizierung. -- InfluxDB 3 Core nutzt einen festen Versionstag statt `latest`, weil der InfluxDB-`latest`-Tag versionsstrategisch im Umbruch ist. -- Die alten Pfade `ops/grafana-influxdb` und `ops/loki` wurden am 2026-05-26 aus dem aktiven Repo entfernt; `monitoring/` ist der einzige Observability-Zielstack. -- Uptime Kuma wurde nach erfolgreichem Blackbox-/Grafana-Smoke-Test entfernt; `monitoring/` ist die Quelle fuer HTTP-Erreichbarkeit und Alerts. - -### Monitoring-Logging-Baseline (2026-05-17) -- `monitoring-loki` laeuft intern auf `monitoring_net`, ohne Traefik-Route und ohne Host-Port. -- `monitoring-promtail` sammelt Docker-Logs ueber `/var/run/docker.sock:ro` und `/var/lib/docker/containers:ro` und schreibt sie an Loki. -- `monitoring-grafana` bekommt provisionierte Datasources fuer Prometheus, Loki und InfluxDB 3 Core. -- Loki-Logdaten sind Diagnosematerial mit begrenzter Retention, keine primaere Restore-Quelle. - -### Authelia ohne Redis-Session-Backend (2026-05-04) -- Authelia nutzt PostgreSQL fuer persistente Storage-Daten, aber bewusst kein Redis-Session-Backend. -- Das haelt den Tier-1-Auth-Pfad einfacher; nach einem Authelia-Restart muessen aktive Sessions neu aufgebaut werden. -- `infra/redis` ist historisch als "shared Cache" angelegt, wird aber faktisch nur von Paperless als App-Cache genutzt. Immich, Nextcloud und Mealie betreiben jeweils eigene Redis-Instanzen in ihren App-internen Netzen; Authelia laeuft bewusst ohne Redis. Eine spaetere Konsolidierung in `apps/paperless/` (analog zu Mealie/Immich/Nextcloud) bleibt fachlich denkbar, ist aber kein priorisierter Schritt. - -### ddns-updater — Netz-Ausnahme -Bleibt bewusst in `frontend_net` statt `backend_net`, weil `backend_net` `internal: true` ist und ddns-updater die Cloudflare-API erreichen muss. - -### mail-archiver — Hybrid-Dienst -Benötigt `backend_net` (PostgreSQL) + `frontend_net` (IMAP-Abruf von GMX/Gmail). Kein reiner Backend-Dienst. Die Web-UI ist via Traefik unter `mail.kaleschke.info` erreichbar und wird durch `authelia@file,secure-headers@file` plus App-eigene Auth geschuetzt. - -### Netzwerk-Standard für Apps mit Datenbanken -- App → `frontend_net` + internes Netzwerk -- Datenbank → nur internes Netzwerk (`internal: true`) - -Beispiel (Mealie): `mealie` → `frontend_net` + `mealie_internal`, `mealie-postgres` → nur `mealie_internal`. +Architektur- und Betriebsentscheidungen werden seit 2026-06-11 zentral in +`docs/DECISIONS.md` gefuehrt (ADR-light: Entscheidung, Kontext, Review-Trigger). +Dieses Dokument haelt nur noch das Zielbild. Neue Entscheidungen werden dort +eingetragen; hier aendert sich nur etwas, wenn das Zielbild selbst betroffen +ist (Netze, Zugangsmodell, Ausnahmen in Sektion 10). --- - ## Schlussformel Dieses Dokument ist keine lose Notiz, sondern das **operative Masterdokument** für die Docker- und Zugriffsarchitektur des Homelabs. diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md new file mode 100644 index 0000000..2823ade --- /dev/null +++ b/docs/DECISIONS.md @@ -0,0 +1,118 @@ +# Entscheidungs-Register (ADR-light) + +Typ: Entscheidung · Stand: 2026-06-11 · Status: aktiv + +Zentrales Register fuer Architektur- und Betriebsentscheidungen. Neueste oben. +Jeder Eintrag: Entscheidung, Kontext, ggf. Alternativen und Review-Trigger. +Lange Incident-Erzaehlungen gehoeren nicht hierher, sondern in den Commit bzw. +Host-Report; hier steht das Destillat. Vorher lebten diese Eintraege verstreut +in `HOMELAB_ARCHITECTURE_MASTER_V2.md` §13, `docs/MASTER_TODO.md` (Geparkt), +`docs/HARDWARE_INVENTORY.md` und der Audit-Restliste. + +--- + +## 2026-06-11 — Doku-Konsolidierung: ein Fakt, ein Zuhause + +**Entscheidung:** Die Dokumentation wird nach `docs/homelab-doku-optimierung.md` (archiviert) konsolidiert: `MASTER_TODO.md` ist die einzige Statusliste, dieses Register die einzige Entscheidungssammlung, `docs/archive/` nimmt abgeschlossene Snapshots auf, Erledigtes verlaesst die Arbeitskopie. Keine Ordner-Restruktur des Bestands. +**Kontext:** 74 Markdown-Dateien / ~9.400 Zeilen; einzelne Sachverhalte waren an 6–9 Stellen dokumentiert; vier parallele Statuslisten. +**Review-Trigger:** Quartals-Gaertnern (siehe `docs/REPO_MAP.md` Doku-Regeln). + +## 2026-06-06 — baerchen: BitLocker und Veeam Storage Encryption bewusst aus + +**Entscheidung:** BitLocker bleibt auf allen Laufwerken deaktiviert; Veeam Storage Encryption bleibt aus (`StorageEncryptionEnabled=False`). +**Kontext:** Recovery laeuft ueber das Veeam-Image auf dem lokalen SMB-Share; kein Key-Management-Aufwand, Restrisiko physischer Diebstahl akzeptiert. +**Review-Trigger:** Off-host-Auslagerung des Windows-Images oder geaendertes Risikoprofil. Runbook: `ops/windows-reinstall/docs/windows-image-backup-baseline.md`. + +## 2026-06-06 — Tailscale: natives Unraid-Plugin kanonisch, restriktive ACL + +**Entscheidung:** Tailscale laeuft ausschliesslich als natives Unraid-Plugin (`tailscale.plg`, Subnet-Router, State im Flash-Backup); der redundante userspace-Docker-Stack `host-services/tailscale/` wurde entfernt. Tailnet-ACL ist tag-basiert restriktiv (`tag:server`/`tag:operator`, `tag:family` schlafend), Default-Allow entfernt. +**Kontext:** Zwei parallele `tailscaled`-Instanzen; nur die Plugin-Instanz routet. Details: `docs/NETWORK_INVENTORY.md`. +**Review-Trigger:** Erstes reales Familiengeraet (Familien-Dienste in ACL konkretisieren). + +## 2026-06-06 — Authelia: 2FA-Catch-all aktiv, OIDC-Rollout gestaffelt + +**Entscheidung:** Catch-all `*.kaleschke.info` -> `two_factor` in Repo- und Host-Config. OIDC-SSO wird app-weise ausgerollt (live: Grafana, Mealie; deployed: Paperless). Immich- und Nextcloud-OIDC sowie Nextcloud-Operator-TOTP sind geparkt, bis Familien-Accounts existieren. +**Kontext:** Nur der Operator hat aktuell einen Authelia-Account; Familien-SSO-Nutzen entsteht erst mit dem Onboarding. Runbook: `docs/AUTHELIA_OIDC_PLAN.md`. +**Review-Trigger:** Family-Onboarding erreicht die App-Login-Ebene. + +## 2026-06-05 — USV geparkt, Cold-Backup Hetzner-only, kein Strom-Monitoring + +**Entscheidung:** Keine USV-Anschaffung dieses Quartal (Power-Loss bewusst akzeptiert). Off-site bleibt allein Hetzner-Borg, keine zweite rotierende Cold-Kopie. Stromverbrauch wird nicht gemessen (kein Messgeraet, kein Beschaffungs-Todo). +**Review-Trigger:** USV: Q3-Review ab 2026-07-01, Hardware-Upgrade oder realer Stromausfall mit Datenfolge. Cold-Backup: Hetzner-Probleme oder stark wachsender Datenwert. Strom: nur bei Anschaffung eines Messgeraets. + +## 2026-06-03 — Fix Common Problems Plugin entfernt, keine Neuinstallation + +**Entscheidung:** FCP wurde deinstalliert und wird bewusst nicht wieder installiert. +**Kontext:** Ein FCP-Scan hing 7 Tage in einem `grep -R`-Symlink-Loop ueber das gesamte Array (3 Cores 100 %, IOWAIT bis 55 %, Load 14.6 -> 1.08 nach Entfernung). Die abgedeckten Risiken uebernehmen Scrutiny, Monitoring-Stack, Posture-Check und Critical-Events-Watcher. +**Review-Trigger:** keiner; Entscheidung ist final. + +## 2026-06-01 — Borg append-only auf Hetzner nicht umgesetzt + +**Entscheidung:** Kein append-only/forced-command auf der Storage Box. +**Kontext:** Der forced-command-Test brach die Key-Auth und musste per Passwort-Recovery zurueckgesetzt werden; Nutzen/Betriebsrisiko-Verhaeltnis unguenstig. Kompensation (Storage-Box-Snapshots) siehe `docs/homelab-optimierung.md` Empfehlung 2. +**Review-Trigger:** Hetzner bietet robusteren Mechanismus, oder Ransomware-Risikoprofil aendert sich. + +## 2026-05-28 — Plex: Reclaim, Traefik-Route ohne ForwardAuth, kein Remote Access + +**Entscheidung:** Plex-Server ist als Operator-Konto geclaimt; externer Zugriff laeuft ausschliesslich ueber Traefik/443 (`plex.kaleschke.info`, File-Provider-Ausnahme wegen Host-Netz), Plex Remote Access und WAN-Port 32400 bleiben aus, keine Authelia-ForwardAuth (native Plex-Auth). +**Kontext:** Preferences waren nach dem Mai-Crash jungfraeulich; Claim-Token wurde nur als Shell-Inline-ENV genutzt, nie persistiert. Details: `docs/SERVICE_CATALOG.md`, `HOMELAB_ARCHITECTURE_MASTER_V2.md` §10. + +## 2026-05-28 — Gitea-SSH (222) bleibt ohne WAN-Freigabe + +**Entscheidung:** Port 222 wird nicht in der FRITZ!Box freigegeben. +**Kontext:** Tailscale ist der Operator-Pfad, der GitHub-Mirror deckt DR-Bootstrap ab, SSH-Brute-Force-Vektor extern vermeiden. + +## 2026-05-28 — paperless-gpt und BentoPDF bleiben aktiv + +**Entscheidung:** Beide Container bleiben trotz geringer Nutzung. paperless-gpt-Abloese wird erst mit Paperless-NGX 3.0 (eigene KI-Features) neu bewertet; BentoPDF ist situatives Tool mit vernachlaessigbarem Footprint und ersetzt Stirling-PDF. +**Review-Trigger:** Paperless-NGX-3.0-Release. + +## 2026-05-26 — AdGuard-Admin nur auf Tailscale-IP, ohne Traefik/2FA + +**Entscheidung:** Admin-UI bleibt auf `100.80.98.33:8082` (Tailscale-only) gebunden; bewusst keine Traefik-/2FA-Umstellung. DNS-Port 53 bleibt direkte Host-Port-Ausnahme. +**Review-Trigger:** Aenderung des Tailnet-Zugangsmodells. + +## 2026-05-25 — Ein Dienst pro Funktion: Jellyfin, Homepage, Uptime-Kuma entfernt + +**Entscheidung:** Plex ist der einzige Medienserver, Glance das einzige Dashboard, Blackbox-Exporter + Prometheus-Alerts + Grafana ersetzen Uptime-Kuma. +**Kontext:** Doppelte Dienste = doppelte Pflege/Attack-Surface. Removal-Checkliste: `docs/WORKFLOW.md`. + +## 2026-05-17 — Monitoring-/Logging-Baseline + +**Entscheidung:** `monitoring/` ist der einzige Observability-Stack (Prometheus, Loki, Promtail, Grafana, Exporter, InfluxDB 3 Core). Loki intern ohne Route, Promtail mit read-only Docker-Socket, Loki-Daten sind Diagnosematerial mit Retention, keine Restore-Quelle. Alte Pfade `ops/loki`/`ops/grafana-influxdb` sind entfernt (Rollback nur via Git-Historie). + +## 2026-05-05 — Stateful Digest-Pinning und Versionspolitik + +**Entscheidung:** Tier-1-/stateful Dienste laufen mit sprechendem Versions-Tag plus Digest (z. B. `postgres:17.x@sha256:...`); mutable Tags wurden 2026-04-17 auf laufende Digests eingefroren. Digest-Pinning ist Reproduzierbarkeit, kein Upgrade-Mechanismus; echte Upgrades sind eigene Aenderungsbloecke. Renovate (live seit 2026-05-29) liefert PRs, kein Auto-Merge. +**Review-Trigger:** Mutable-Tag-Restbestand siehe `docs/homelab-optimierung.md` Empfehlung 1. + +## 2026-05-04 — Authelia ohne Redis-Session-Backend + +**Entscheidung:** Authelia nutzt PostgreSQL fuer Storage, aber kein Redis-Session-Backend; nach Restart werden Sessions neu aufgebaut. +**Kontext:** Haelt den Tier-1-Auth-Pfad einfach. `infra/redis` ist faktisch nur Paperless-Cache; Konsolidierung nach `apps/paperless/` bleibt denkbar, unpriorisiert. + +## 2026-05-04 — Komodo-Self-Stack: Reconcile-Regel nach Drift + +**Entscheidung:** Der Komodo-Self-Stack laeuft aus `/mnt/user/services/stacks/komodo/compose.yaml` (Quelle: `ops/komodo/docker-compose.yml`). Bei Self-Stack-Drift kein pauschales `docker compose up -d`, wenn der Dry-run `komodo-mongo` recreaten wuerde; Core/Periphery gezielt mit `--no-deps` neu erstellen, Mongo unangetastet lassen. +**Kontext:** Drift-Recovery 2026-05-04 (Repair-YAMLs aus `/tmp`); Sicherungen unter `/mnt/user/appdata/komodo/_drift_backup_2026-05-04/`. + +## 2026-04-19 — Nextcloud als klassischer Stack, nicht AIO; native Auth + +**Entscheidung:** Nextcloud laeuft als App + eigene PostgreSQL + eigene Redis (kein AIO), ohne zentrale ForwardAuth (Browser-/Client-/WebDAV-Flows brauchen native Auth). + +## 2026-04-12 — Borg-Scope enthaelt bewusst /local/secrets + +**Entscheidung:** Borg sichert ausgewaehltes Secret-Material (`/local/secrets`) als Teil der DR-Strategie; `borg-ui` hat dafuer breite, bewusste Mounts. Dumps statt Raw-DB-Pfade sind der primaere Restore-Weg. +**Kontext:** `ops/borg-ui/BACKUP_SCOPE.md`. + +## 2026-03-28/29 — GitOps-Fundament + +**Entscheidung:** Komodo ersetzt Portainer als alleiniger Stack-Manager (Docker-Socket-Ausnahme, native Auth ohne pauschale ForwardAuth wegen Webhooks/`/ws/periphery`). Traefik routet ausschliesslich ueber Docker-Labels; File-Provider nur fuer `middlewares.yml`, `tls.yml`, `dashboards.yml` (+ dokumentierte `plex.yml`-Ausnahme). AdGuard Home + Unbound ersetzen Pi-hole. +**Kontext:** Konkurrierende `@file`-/`@docker`-Router hatten Fehlrouting verursacht; Regel: keine neuen Service-Routen im File-Provider. + +## Aelteres / Sonderfaelle + +- **Paperless Stack-ENV-Ausnahme:** `PAPERLESS_DBPASS`/`PAPERLESS_REDIS` bleiben Komodo-Stack-ENV (kein `_FILE`-Support im Image); Konsequenzen fuer DR siehe `docs/DISASTER_RECOVERY.md` Phase 2. +- **ddns-updater in `frontend_net`:** braucht Cloudflare-API; `backend_net` ist internal. +- **mail-archiver Hybrid:** `frontend_net` (IMAP) + `backend_net` (DB), App-Auth zusaetzlich zu Authelia. +- Vollstaendige technische Ausnahmen-Liste mit Begruendung: `HOMELAB_ARCHITECTURE_MASTER_V2.md` §10 (bleibt dort autoritativ). diff --git a/docs/ROLLBACK.md b/docs/ROLLBACK.md index f6f304e..c903fb4 100644 --- a/docs/ROLLBACK.md +++ b/docs/ROLLBACK.md @@ -1,6 +1,10 @@ -# Rollback Guide - Homelab +# Rollback Guide - Homelab + +Typ: Runbook · Stand: 2026-06-11 · Status: aktiv Dieses Dokument beschreibt den sicheren Rueckweg im aktuellen GitOps-Betrieb. +Rollback-Anleitungen fuer bereits entfernte Dienste (Uptime-Kuma, Grafana-/ +InfluxDB-Altstack, Stirling-PDF) liegen in der Git-Historie, nicht mehr hier. --- @@ -72,59 +76,14 @@ Bei Problemen mit Borg UI oder Dump-Automatisierung: 3. Persistenz unter `/mnt/user/appdata/borg-ui/` und `/mnt/user/backups/borg/dumps/` nicht blind loeschen 4. Restore zuerst in einen Testpfad schreiben, nicht direkt in Produktivpfade -## BentoPDF / Stirling-PDF Rollback +## Monitoring-Stack Rollback -Bei Problemen mit BentoPDF: - -1. Git-Stand auf die letzte funktionierende Stirling-PDF-Compose zuruecknehmen oder gezielt `apps/bentopdf` wieder durch `apps/stirling-pdf` ersetzen -2. Commit + Push nach Gitea -3. betroffenen Stack in Komodo redeployen -4. `https://pdf.kaleschke.info` pruefen - -Die alte Stirling-PDF-Persistenz unter `/mnt/user/appdata/stirling-pdf` nicht loeschen, solange der BentoPDF-Ersatz nicht fachlich abgenommen ist. - -## Grafana / InfluxDB Rollback - -Vor dem ersten produktiven Einsatz reicht es, den vorbereiteten Stack nicht zu deployen oder per Ruecknahme-Commit aus dem Repo zu entfernen. - -Nach einem Deploy: - -1. alten Grafana/InfluxDB-Stack in Komodo gestoppt lassen; der fruehere Compose-Pfad `ops/grafana-influxdb` ist seit 2026-05-26 nicht mehr im aktiven Repo -2. Persistenz unter `/mnt/user/appdata/grafana` und `/mnt/user/appdata/influxdb3` unangetastet lassen -3. Secrets unter `/mnt/user/appdata/secrets/grafana_admin_password.txt`, `/mnt/user/appdata/secrets/grafana_influxdb_token.txt` und `/mnt/user/appdata/secrets/influxdb3_admin_token.json` nur nach bewusstem Entscheid entfernen -4. Grafana-Domain und InfluxDB-Zugriff testen, bis klar ist, dass keine produktiven Dashboards oder Writer mehr davon abhaengen - -## Monitoring-Zielstack Rollback - -Der Zielzustand ist `monitoring/` als einziger Observability-Stack. Bei Problemen nach der Migration: +`monitoring/` ist der einzige Observability-Stack. Bei Problemen: 1. `monitoring` in Komodo stoppen oder auf den letzten funktionierenden Commit zurueckgehen -2. nur im echten Notfall die abgeloesten Altstaende aus der Git-Historie vor dem Repo-Cleanup wiederherstellen, z. B. aus Commit `ff5991c`; nicht dauerhaft parallel zum Zielstack betreiben -3. named volumes `prometheus_data`, `loki_data`, `promtail_positions`, `grafana_data` sowie `/mnt/user/appdata/influxdb3` nicht blind loeschen -4. Secrets `monitoring_grafana_admin_password.txt`, `monitoring_grafana_influxdb_token.txt` und `influxdb3_admin_token.json` nur nach bewusstem Entscheid entfernen -5. Home Assistant Writer erst wieder umstellen, wenn `curl -i http://192.168.178.58:8181/` erwartbar `401 Unauthorized` liefert -6. Grafana-Datasources `Prometheus`, `Loki` und `InfluxDB 3 Core` testen - -## Uptime Kuma Removal Rollback - -Falls die Blackbox-/Grafana-Ablösung unerwartet nicht ausreicht: - -1. per Ruecknahme-Commit `ops/uptime-kuma/docker-compose.yml`, die Blackbox-/Glance-/Authelia-Referenzen und die Restore-Freshness-Pruefung auf den letzten Uptime-Kuma-Stand zurueckbringen -2. nach Gitea pushen und den Uptime-Kuma-Stack in Komodo neu anlegen oder aus dem letzten Stack-Backup wiederherstellen -3. `/mnt/user/appdata/_archive/uptime-kuma-removed-2026-05-25` nach `/mnt/user/appdata/uptime-kuma` zurueckverschieben, falls die Archivierung bereits erfolgt ist -4. `https://uptime.kaleschke.info` und die Monitore pruefen -5. erst danach den Blackbox-/Grafana-Zielzustand erneut bewerten - -## Glance Dashboard Rollback - -Vor dem ersten produktiven Einsatz reicht es, den vorbereiteten Stack `ops/glance` nicht zu deployen oder per Ruecknahme-Commit aus dem Repo zu entfernen. - -Nach einem Deploy: - -1. `glance` in Komodo stoppen oder auf den letzten funktionierenden Commit zurueckgehen -2. keine Produktivdaten loeschen; Glance nutzt nur Repo-Konfiguration und Stack-ENV -3. pruefen, ob `https://glance.kaleschke.info` nicht mehr geroutet wird oder wieder den erwarteten Stand zeigt -4. der `glance-docker-socket-proxy` darf nicht separat als Dauercontainer laufen bleiben +2. named volumes `prometheus_data`, `loki_data`, `promtail_positions`, `grafana_data` sowie `/mnt/user/appdata/influxdb3` nicht blind loeschen +3. Secrets (`monitoring_grafana_admin_password.txt`, `monitoring_grafana_influxdb_token.txt`, `influxdb3_admin_token.json`) nur nach bewusstem Entscheid entfernen +4. Grafana-Datasources `Prometheus`, `Loki` und `InfluxDB 3 Core` testen --- @@ -132,19 +91,11 @@ Nach einem Deploy: Bevorzugte Quellen: -- Borg-Restore -- erzeugte PostgreSQL-/MariaDB-Dumps -- bekannte Appdata-Snapshots +- Borg-Restore (zuerst in Testpfade unter `/mnt/user/backups/restore-lab/`) +- erzeugte Dumps unter `/mnt/user/backups/borg/dumps/latest` +- bekannte Appdata-Archivstaende unter `/mnt/user/appdata/_archive/` -Beispiele: - -```bash -cp -r /mnt/user/appdata/ /mnt/user/backup/ -``` - -```bash -pg_dumpall > /mnt/user/backup/pg_dump_$(date +%Y%m%d).sql -``` +Dienst-spezifische Restore-Quellen, Dumps und Smoke-Tests stehen in `docs/RESTORE_MATRIX.md`. ---