Commit Graph

773 Commits

Author SHA1 Message Date
Micha 1fcdb68221 docs: consolidate restore documentation into ops/restore-tests
- merge RESTORE_HANDBOOK.md into ops/restore-tests/README.md (single
  operations doc; restore status lives only in RESTORE_MATRIX maturity
  table)
- RESTORE_MATRIX.md: extract embedded runbook drafts (261 -> 141 lines);
  unraid-flash and tailscale stubs become ops/restore-tests runbooks,
  adguard/redis checklists superseded by validated scripts
- delete six historical pre-first-run *-plan.md files (runbook + script
  are the source of truth since the validated first runs)
- SERVICES_RECOVERY: drop completed task table; DISASTER_RECOVERY:
  point related docs and section 11 to MASTER_TODO/schedule

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:11:16 +02:00
Micha 489a429316 docs: single status list - dissolve audit restliste, slim AI context
- MASTER_TODO.md is now the only status list: parked decisions point to
  DECISIONS.md, done log capped at 5 condensed entries
- delete AUDIT_2026-05-25_TODO.md (open items and parked decisions fully
  covered by MASTER_TODO/DECISIONS)
- AI_CONTEXT.md: drop duplicated status block, keep rules and pointers
- EXTERNAL_DEPENDENCIES.md: condense review log to recent entries
- fix references in DR_WORKSTATION_SETUP, EXTERNAL_OPERATOR_RUNBOOK,
  STORAGE_LAYOUT, REPO_MAP, docs/README

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:08:43 +02:00
Micha 513f41b852 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 <noreply@anthropic.com>
2026-06-11 07:06:18 +02:00
Micha c80b51f585 docs: introduce docs/archive, remove finished sprint boards and generated report
- docs/archive/2026/ with index README: DR tabletop drill, workstation
  audits, HA/Ecowitt draft, pre-Borg backup audit, finished windows
  reinstall project docs
- delete weekend sprint boards (content preserved in MASTER_TODO done log
  and git history)
- untrack generated ops/policy-checks/last-report.md and gitignore it
- fix references (CLAUDE.md, docs/README.md, ops/windows-reinstall/README.md)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:02:57 +02:00
Micha 42ed59a4d7 docs: commit pending status updates from 2026-06-06 sprint wrap-up
Preserves uncommitted working-copy updates (Veeam recovery test done,
BitLocker decision, ACL rollout, freshness negative test) before the
documentation consolidation restructures these files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:00:25 +02:00
Micha 58c3324557 docs: add homelab documentation optimization proposal
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 06:36:53 +02:00
Micha d48d473942 docs: add homelab optimization assessment
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:40:05 +02:00
Micha e80e5dd49f renovate: komodo-Stack (inline-managed) aus Tracking nehmen
Der komodo-Stack wird in Komodo inline (file_contents) verwaltet, nicht aus dem Repo deployed. Renovate-PRs darauf wirken zur Laufzeit nicht und erzeugen Git-Komodo-Scheinsicherheit. Daher: ops/komodo/** in ignorePaths, mongo-Digest auf den real laufenden Stand zurueckgesetzt, Inline-Ausnahme in docs/RENOVATE.md und im Compose-Header dokumentiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 20:34:52 +02:00
Micha 3c339474a7 Merge pull request 'chore(deps): update mongo:8.0.23 docker digest to 73ee318' (#13) from renovate/mongo-8.0.23 into master
Reviewed-on: #13
2026-06-10 18:27:13 +00:00
Micha c79afdfab0 Merge pull request 'chore(deps): update docker.n8n.io/n8nio/n8n docker tag to v2.26.2' (#17) from renovate/docker.n8n.io-n8nio-n8n-2.x into master
Reviewed-on: #17
2026-06-10 18:24:23 +00:00
Micha 8172793c68 Merge pull request 'chore(deps): update nextcloud docker tag to v33.0.5' (#16) from renovate/nextcloud-33.x into master
Reviewed-on: #16
2026-06-10 18:19:56 +00:00
Micha 8e46440944 Merge pull request 'chore(deps): update shaanmajid/unbound:1.25.1 docker digest to f140db0' (#14) from renovate/shaanmajid-unbound-1.25.1 into master
Reviewed-on: #14
2026-06-10 18:13:58 +00:00
Micha dfe1dc1c99 Merge pull request 'chore(deps): update traefik:v3.7 docker digest to fcdef59' (#15) from renovate/traefik-v3.7 into master
Reviewed-on: #15
2026-06-10 18:06:09 +00:00
Micha 4007da3302 docs: Runbook fuer Komodo-Bulk-Deploy-DNS-Ausfall
Bulk-Renovate-Merge loest parallele Komodo-Deploys aus; Image-Pulls scheitern mit DNS connection refused, weil AdGuard (einziger Host-Resolver) im selben Batch recreated wird. Runbook haelt Symptom, Ursache, Sofortmassnahme (Unraid DNS2) und Betriebsregel fest. Verweis in REPO_MAP ergaenzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 19:52:34 +02:00
Micha 9836ea3c4f Merge pull request 'chore(deps): update minor-and-patch-updates' (#12) from renovate/minor-patch-updates into master
Reviewed-on: #12
2026-06-10 14:41:25 +00:00
renovate 803f84b3af chore(deps): update docker.n8n.io/n8nio/n8n docker tag to v2.26.2 2026-06-10 14:32:41 +00:00
renovate d05ca63545 chore(deps): update nextcloud docker tag to v33.0.5 2026-06-10 14:32:09 +00:00
renovate 9847baf327 chore(deps): update minor-and-patch-updates 2026-06-10 14:32:08 +00:00
renovate 8ec5bc55d9 chore(deps): update traefik:v3.7 docker digest to fcdef59 2026-06-10 14:31:35 +00:00
renovate 9c844074e0 chore(deps): update shaanmajid/unbound:1.25.1 docker digest to f140db0 2026-06-10 14:31:33 +00:00
Micha c126b71852 renovate: Kritische Kerninfra aus minor-patch-Sammel-PR ausgliedern
Traefik (Public-Entrypoint), Unbound (DNS), n8n und Nextcloud bekommen eigene PRs statt im gruppierten minor-and-patch-updates-PR zu landen. Erzwingt kontrollierten, einzeln reviewbaren Merge pro kritischem Dienst (WORKFLOW.md: keine mehreren kritischen Dienste gleichzeitig migrieren).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 16:22:12 +02:00
Micha e89b88a513 report: Noise-Eskalations-Befreiung fuer dauerhaft-laute Benign-Patterns
Bekannte Noise-Patterns, die strukturell sehr laut sind (Unraid-mdadm-Spam
~5760/Tag, Fritz!Box-SOA ~1170/Tag), hielten den Report-Status dauerhaft
auf >= WARNUNG ueber noise_threshold_exceeded und entwerteten damit die
Ampel - das System konnte nie OK erreichen, egal wie gesund.

Neue Datei noise-escalation-exempt.patterns listet solche Patterns. Sie
zaehlen weiterhin als Noise und erscheinen in der Breakdown-Tabelle (jetzt
mit Hinweis-Spalte "eskalations-befreit"), zaehlen aber nicht mehr zu
noise_threshold_exceeded. Neue/unerwartete laute Patterns eskalieren
weiterhin zur WARNUNG. Jede Befreiung traegt Begruendung + Recheck.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 15:15:10 +02:00
Micha 8bb250220b immich-ml: --no-control-socket gegen gunicorn-25.1.0 Worker-Hang
Ersetzt den wirkungslosen LD_PRELOAD-Versuch durch den dokumentierten
Root-Cause-Fix. immich_machine_learning blieb dauerhaft unhealthy: der
gunicorn-Worker haengt nach "Control socket listening" in futex und
erreicht nie "Application startup complete" (/ping -> Timeout). Ursache ist
der in gunicorn 25.1.0 neu eingefuehrte, fehlerhafte Control-Socket
(bestaetigt: gunicorn#3510, immich#27228, Regression seit Immich 2.6).

GUNICORN_CMD_ARGS=--no-control-socket deaktiviert das Feature. immich-ml
startet gunicorn als Subprozess (python -m gunicorn), der GUNICORN_CMD_ARGS
aus der Env liest und anhaengt; das Flag --no-control-socket
(config: control_socket_disable) ist in diesem gunicorn-Build als gueltig
verifiziert. Reversibel; bei gefixter Immich-Release wieder entfernen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:36:01 +02:00
Micha 2f64aee109 report: unhealthy-Container namentlich + Image-Age-Allowlist
Zwei Verbesserungen am Daily Operations Report, ausgeloest durch den
versteckten immich_machine_learning-Ausfall (lief 2,3 Tage unhealthy,
weil der Report nur "unhealthy=1" zaehlte, ohne Name/Grund):

1. collect_container_state: neue Sektion "Unhealthy Container" listet jeden
   unhealthy Container mit FailingStreak und letztem Healthcheck-Output.
   So ist sofort sichtbar WELCHER Container und WARUM.

2. collect_image_freshness: neue Image-Age-Allowlist
   (image-age-allow.patterns). Bewusst gepinnte, aber aktuelle/empfohlene
   Images (immich_postgres = exakt Immichs Pin; blackbox-exporter v0.28.0 =
   latest) werden mit Recheck-Datum von der Ueberalterungs-Warnung
   ausgenommen. Nach Ablauf des Recheck-Datums greift die Ausnahme nicht
   mehr -> erzwingt Neubewertung statt stillen Alterns. Top-10-Tabelle hat
   jetzt eine Hinweis-Spalte (ueberaltert / bewusst gepinnt).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:08:44 +02:00
Micha ed55b88ec1 immich-ml: LD_PRELOAD leeren gegen gunicorn-25.1.0-Fork-Deadlock
immich_machine_learning haengt seit dem 7.6. unhealthy: der gunicorn-Worker
bleibt nach "Control socket listening" in futex_do_wait stehen und erreicht
nie "Application startup complete" (/ping -> ConnectTimeout/ReadTimeout).
Kein OOM (22 GB frei), kein Disk-I/O-Wait, laeuft als root, Socket wird
erstellt - klassischer Fork-Deadlock von mimalloc (LD_PRELOAD) im geforkten
Worker unter gunicorn 25.1.0.

mimalloc per LD_PRELOAD="" deaktiviert. Reine Allocator-Optimierung,
funktional unkritisch, reversibel. Bekannte Upstream-Regression seit
Immich 2.6 (immich#27228, #22317) ohne offiziellen Fix; Restart und
force-recreate sind dort als wirkungslos dokumentiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:02:27 +02:00
Micha ce747f687f ops-report: cert-dedup, blackbox-DNS auf AdGuard, neue Noise-Patterns
Behebt drei Befunde aus dem Operations-Report 2026-06-10:

- daily-status-report.sh: Zertifikate werden vor der Auswertung pro
  Domain-Set dedupliziert; nur das laengstlaufende Cert zaehlt. Traefik
  haelt waehrend der Erneuerung altes + neues Cert in acme.json, was
  bisher eine falsche KRITISCH-Warnung (traefik.kaleschke.info 5 Tage)
  ausloeste, obwohl das neue Cert 65 Tage Restlaufzeit hat.

- monitoring/blackbox-exporter: DNS von 1.1.1.1/8.8.8.8 auf AdGuard
  (172.23.0.3 via dns_net) umgestellt. Externe Resolver lieferten die
  WAN-IP, was Hairpin-NAT-Timeouts (9,5s) bei Probes von cloud/glances
  verursachte (662 Fehler/Tag).

- log-noise.patterns: Fritz!Box-SOA-Fehler (AdGuard, RFC-1035-Verstoss)
  und fehlendes grafana-amazonprometheus-datasource-Plugin als bekanntes
  Rauschen klassifiziert (~1800 Zeilen/Tag).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:06:52 +02:00
renovate cf11b4d75b chore(deps): update mongo:8.0.23 docker digest to 73ee318 2026-06-10 04:21:10 +00:00
Micha 796901ec6b docs(network): Post-Upgrade Posture-Recheck Unraid 7.3.1 + AdGuard/libvirt-:53-Vorfall
Nach Major-Upgrade 7.2.4 -> 7.3.1 read-only Host-Listener gegen dokumentierte
Annahmen geprueft: alle Ausnahmen intakt (InfluxDB 127.0.0.1:8181, AdGuard nur
Tailscale, Gitea-SSH 222 LAN/TS, Traefik einziger 80/443-Owner, libvirt :53 weg).
Docker-Socket-Lage festgehalten (nur komodo-periphery RW; Traefik C-3 ro, kein Regress).
AdGuard-Boot-Race (libvirt-Default-Netz belegte :53 vor AdGuard) + Fix dokumentiert;
Dauerfix-Empfehlung VM-Manager aus. SSH-Haertung nach Upgrade verifiziert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:26:59 +02:00
Micha de7b714b4d docs(network): SSH-Host-Haertung dokumentieren (key-only root, upgrade-sichere Persistenz)
Host gehaertet 2026-06-07: PermitRootLogin prohibit-password,
PasswordAuthentication no, KbdInteractiveAuthentication no; PubkeyAuthentication yes.
Persistenz upgrade-sicher via idempotentem /boot/config/ssh-harden.sh aus
/boot/config/go (sshd -t vor HUP-Reload, Syslog-Selbst-Verifikation).
Manueller Post-Upgrade-Check und Rollback dokumentiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 11:02:07 +02:00
Micha 8045e22873 authelia-oidc: Immich+Nextcloud bis Onboarding geparkt; aktive Phase abgeschlossen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:18:54 +02:00
Micha 52f8c2adcb posture-check: Tailscale-Docker aus CRITICAL_CONTAINERS entfernen (Container abgebaut)
Verhindert Dauer-ntfy-Alarm fuer den entfernten userspace-Docker-Tailscale. Natives Tailscale-Plugin ist kein Container und wird hier bewusst nicht geprueft.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:15:07 +02:00
Micha 0ddae675a8 plex: add web redirect for public route 2026-06-06 13:45:47 +02:00
Micha 7ce8e948cd plex: route host network service via traefik file 2026-06-06 13:44:22 +02:00
Micha 2a87220862 plex: expose via traefik domain 2026-06-06 13:41:39 +02:00
Micha f2d4cad566 paperless: Authelia OIDC SSO additiv (allauth, extra_hosts)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:41:16 +02:00
Micha e7370e4820 authelia-oidc: Mealie erledigt + extra_hosts-Gotcha dokumentieren
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:37:34 +02:00
Micha dc26eb313c mealie: extra_hosts auth.kaleschke.info -> Host-IP fuer OIDC-Erreichbarkeit
Mealie-Container konnte auth.kaleschke.info nicht aufloesen/erreichen (httpx.ConnectTimeout beim OIDC-Discovery). extra_hosts-Muster wie Komodo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:34:09 +02:00
Micha dc7cbfa6cd mealie: Authelia OIDC SSO additiv (lokaler Login bleibt)
OIDC_AUTH_ENABLED + Authelia-Provider, Secret via ${MEALIE_OIDC_CLIENT_SECRET} (Stack-ENV). Kein Auto-Redirect, Self-Signup an. Authelia-Client mealie (one_factor) host-seitig angelegt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:29:01 +02:00
Micha cf9ca59eb1 docs: close baerchen veeam recovery test 2026-06-06 13:27:31 +02:00
Micha d2a9c3b8cb docs: record baerchen veeam recovery usb boot 2026-06-06 13:25:53 +02:00
Micha 0177350e64 docs: close guest iot network setup 2026-06-06 13:23:35 +02:00
Micha 2f3a029098 authelia-oidc: Grafana-Proof als erledigt dokumentieren + Secret eintragen
- SECRETS_MAP: grafana_oidc_client_secret (Datei + __FILE, Hash in Authelia-Host-Config)
- AUTHELIA_OIDC_PLAN: Stufe 1 (Grafana) als erledigt markiert
- MASTER_TODO: OIDC-Proof verifiziert, naechster Schritt Familien-Apps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:17:29 +02:00
Micha a4c79d9d81 docs: record guest iot preflight 2026-06-06 13:14:07 +02:00
Micha 18a90fbb4b ops: add guest iot network preflight 2026-06-06 13:13:01 +02:00
Micha 30f076c85a monitoring/grafana: OIDC-SSO via Authelia (Stufe-1-Proof)
- generic_oauth gegen Authelia (client_id grafana, PKCE, client_secret via __FILE aus /mnt/user/appdata/secrets/grafana_oidc_client_secret)
- Traefik-Middleware authelia@file entfernt -> OIDC ist jetzt die Auth; lokaler Grafana-Admin bleibt Fallback
- Authelia-Client wurde host-seitig angelegt (Secret nur als Host-Datei + Hash in Authelia-Config)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:11:00 +02:00
Micha 6e65f81503 docs: record restore freshness negative alert test 2026-06-06 13:04:42 +02:00
Micha 6123584a02 ops: make freshness negative ntfy call robust 2026-06-06 13:03:05 +02:00
Micha c33e29016b ops: add restore freshness negative alert test 2026-06-06 13:02:14 +02:00
Micha 2628a0c795 authelia-oidc: Plan + Runbook fuer app-uebergreifendes SSO
- docs/AUTHELIA_OIDC_PLAN.md: v4.39-Client-Schema, Endpoints, Secret-Erzeugung, Rollout-Reihenfolge (Grafana-Proof zuerst, dann Familien-Apps), Grafana-Schritt-fuer-Schritt
- MASTER_TODO: OIDC-Punkt auf Plan verweisen, naechster Schritt Grafana-Proof
- README: Doku-Index ergaenzt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:58:38 +02:00
Micha c7eed6bdad todo: Authelia Rest-2FA als komplett erledigt markieren (Host-Merge + 2FA-Login verifiziert)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:55:23 +02:00