New services/authelia-diff.sh compares the access_control: section of the repo baseline against the live host configuration.yml. OIDC clients, identity providers, and secret values stay out of scope by design. Exit codes: 0 ok, 1 drift, 2 file missing, 3 section missing, 4 tool missing. posture-check.sh gains check_authelia_config_drift, which calls the diff script and reports drift as warning (not critical). SKIP_AUTHELIA_DRIFT=1 opts out; AUTHELIA_DIFF_SCRIPT overrides the path. WORKFLOW.md gets a dedicated "Ausnahme: Authelia configuration.yml" section analogous to the Traefik dynamic-config exception, with the mandatory repo->host merge workflow and the env-variable contract. Smoke-tested locally: identical files rc=0, ACL change rc=1 with proper unified diff, non-ACL change (session.default_redirection_url) correctly ignored. Operator follow-up: set up a read-only repo mirror at /mnt/user/services/homelab-infra/ so the check finds a current baseline. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
14 KiB
Workflow - GitOps / No-Drift Regeln
Dieses Dokument definiert den verbindlichen Arbeitsablauf fuer Aenderungen an der Homelab-Infrastruktur.
Ziel
Es darf keine dauerhafte Abweichung zwischen:
- Gitea Online
- lokalem Clone
- Komodo-Stacks
- laufenden Docker-Containern
- Host-Konfiguration
geben.
Grundsatz:
Gitea Online ist die operative Quelle der Wahrheit.
Betriebsmodell
Die Rollen sind bewusst getrennt:
- Gitea Online ist
originund damit der verbindliche Sollzustand. - Der lokale Clone ist die Arbeitskopie fuer Aenderungen.
- Komodo deployed aus Gitea und ist kein Bearbeitungsort.
- Der Host ist Laufzeit, nicht Quelle der Wahrheit.
Operative Hierarchie
origin/masterin Gitea- lokaler Clone auf dem Windows-PC
- Komodo-Deployments / Webhooks
- laufende Container und Host-Dateien
Wenn diese Ebenen voneinander abweichen, gewinnt immer zuerst Git und nicht der manuelle Live-Zustand.
Standard-Workflow
Aenderungen werden immer in dieser Reihenfolge durchgefuehrt:
- Lokal synchronisieren
- Lokal aendern
- Commit erzeugen
- Push nach Gitea
- Komodo reagiert automatisch per Webhook
- Ergebnis testen
- Doku pruefen und nachziehen
Standardwerkzeug fuer den Alltag
Der bevorzugte lokale Workflow ist:
- GitHub Desktop fuer
Fetch,Pull,Commit,Push - Editor nach Wahl fuer Datei-Aenderungen
- Gitea Web fuer Historie, Review und kleine Notfaelle
- Komodo nur fuer Deploy-Status, Logs und Stack-Sicht
Tagesablauf mit GitHub Desktop
Vor lokaler Arbeit:
- GitHub Desktop oeffnen
Fetch origin- wenn noetig
Pull origin
Nach lokaler Arbeit:
- Aenderungen pruefen
- bei Compose-/Backup-/Restore-Aenderungen relevante manuelle Repo-Checks ausfuehren
ops/policy-checks/check_repo.ps1ops/restore-tests/check-restore-freshness.ps1oder gezielte Restore-Checks
- Commit mit sauberer Nachricht
Push origin- Komodo-Webhook im Hinterkopf behalten
Wenn online in Gitea gearbeitet wurde
Web-Aenderungen in Gitea sind erlaubt, aber nicht der Normalfall.
Wenn online etwas geaendert wurde, gilt vor der naechsten lokalen Arbeit:
- GitHub Desktop oeffnen
Fetch originPull origin- erst dann lokal weiterarbeiten
Sonst entsteht Drift zwischen Gitea Online und lokalem Clone.
Komodo-Regeln
Komodo ist in diesem Setup:
- primaeres Deployment-Werkzeug
- GitOps-Consumer fuer die Stacks
- Monitoring- und Status-Werkzeug
Deshalb gilt
- Stack-Konfiguration nur im Repository anpassen
- nicht im Komodo-Web-Editor arbeiten
- Pushes koennen automatisch einen Komodo-Deploy ausloesen
- wenn Komodo und Git voneinander abweichen, gewinnt Git
Pflicht bei neuen Komodo-Stacks
Jeder neue produktive Komodo-Stack, der aus Micha/homelab-infra deployed wird, braucht einen aktiven Gitea-Webhook auf die aktuelle Komodo-Stack-ID.
Pflichtschritte beim Anlegen:
- Stack in Komodo aus Gitea anlegen
webhook_enabledin Komodo aktivieren- passenden Gitea-Webhook fuer die aktuelle Stack-ID anlegen
- Gitea-Hook gegen
http://komodo-core:9120/listener/github/stack/<stack-id>/deploypruefen - einen Push oder Test-Delivery ausloesen und
last_status/Komodo-Deploy pruefen - Ausnahmen explizit dokumentieren
Regel: Kein neuer produktiver GitOps-Stack ohne funktionierenden Gitea->Komodo-Webhook. Bewusste Ausnahmen muessen im selben Aenderungsblock dokumentiert werden, inklusive Grund und Alternativ-Deploy-Weg.
Der Standardfall nutzt den globalen KOMODO_WEBHOOK_SECRET aus der Komodo-Host-.env, ausser Komodo zeigt fuer den Stack explizit ein eigenes per-Stack-Secret.
Ausnahme: Komodo-Zugangsmodell
Komodo bleibt bewusst ohne zentrale Traefik-ForwardAuth-Middleware.
Grund:
- Komodo hat eigene Authentifizierung
- Komodo nutzt REST- und WebSocket-Endpunkte
- Webhooks laufen ueber
/listener/... - Periphery nutzt den speziellen WebSocket-Pfad
/ws/periphery
Deshalb wird Komodo aktuell nur ueber Traefik veroeffentlicht, aber nicht pauschal mit authelia@file vorgeschaltet.
Regel: Aenderungen an Komodo-Auth, Komodo-Routing oder vorgeschalteter Middleware nur nach expliziter Wirkungspruefung auf:
- UI-Login
- Gitea-Webhooks
- Periphery-Verbindung
- API-/Automationszugriffe
Verbotene Arbeitsweise
Folgende Dinge sind grundsaetzlich zu vermeiden:
- Aenderungen direkt im Komodo-Web-Editor
- Aenderungen direkt per
docker run - Aenderungen an laufenden Containern ohne Repo-Anpassung
- spontane Host-Hotfixes ohne Nachdokumentation
- Secrets im Git-Repository
- mehrere kritische Dienste gleichzeitig migrieren
Erlaubte Arbeitsweise
Erlaubt und gewuenscht sind:
- Aenderungen an Compose-Dateien im Git-Repo
- Commit + Push vor jedem produktiven Deploy
- GitHub Desktop als Standardweg fuer den lokalen Sync
- Gitea Web fuer Review, Historie und kleine Hotfixes
- Host-Hotfixes nur im Ausnahmefall mit sofortiger Nachpflege im Repo
No-Drift-Prinzip
Definition
Configuration Drift liegt vor, wenn der reale Zustand vom Git-Zustand abweicht.
Beispiele:
- laufender Container wurde manuell veraendert
- lokaler Clone ist nicht mehr auf dem Stand von
origin/master - Komodo-Stack entspricht nicht mehr dem Repo
- Host-Dateien wurden angepasst, aber nicht dokumentiert
- Traefik dynamic config wurde lokal geaendert, aber Git weiss nichts davon
Regel
Wenn Drift erkannt wird, gilt:
- Drift nicht ignorieren
- Drift sofort benennen
- entscheiden:
- Repo an Realitaet anpassen
- oder Realitaet an Repo zurueckfuehren
- erst danach weiterarbeiten
Pflichtcheck bei Drift-Verdacht
Vor jedem Reparaturversuch muessen die Ebenen getrennt geprueft werden:
- lokaler Clone
- Gitea
origin/master - Komodo Stack Workspace
- Docker Runtime
- Host-Netzwerklistener
Das detaillierte Runbook steht in docs/GITOPS_DRIFT_RUNBOOK.md.
Regel: HostConfig.PortBindings allein beweist keinen aktiven Host-Port. Entscheidend sind NetworkSettings.Ports, docker ps, ss -ltnp und ein echter curl gegen den Host-Port.
Stop-Regel: Wenn zwei Reparaturversuche nicht zum erwarteten Ergebnis fuehren, keine weiteren Schreibbefehle ausfuehren. Erst die Pflichtmatrix aus dem Runbook ausfuellen.
Ausnahmefall: Hotfix auf dem Host
Manchmal ist ein Live-Hotfix noetig. Das ist erlaubt, aber nur unter diesen Bedingungen:
- Hotfix nur wenn der Dienst sonst nicht funktioniert
- Aenderung sofort dokumentieren
- Aenderung danach ins Git-Modell ueberfuehren
- kein stiller Dauerzustand
Pflicht bei Hotfixes
- Was wurde geaendert?
- Wo wurde es geaendert?
- Warum war es noetig?
- Muss diese Aenderung ins Repo uebernommen werden?
- Ist ein Rollback dokumentiert?
Ausnahme: Traefik Dynamic Config
Diese Dateien werden von Komodo nicht automatisch deployed.
Komodo deployed ausschliesslich docker-compose.yml-Dateien. Die Traefik-Konfigurationsdateien unter traefik/dynamic/ im Git-Repo werden nicht automatisch auf den Host uebertragen.
Diese Ausnahme bleibt bewusst bestehen. Der File-Provider wird weiterhin nur fuer zentrale Middlewares, TLS und Dashboard-Konfiguration genutzt, waehrend Service-Routing ueber Docker-Labels laeuft.
Betroffene Dateien
| Git-Pfad | Host-Pfad (NAS) |
|---|---|
traefik/dynamic/middlewares.yml |
/mnt/user/appdata/traefik/dynamic/middlewares.yml |
traefik/dynamic/tls.yml |
/mnt/user/appdata/traefik/dynamic/tls.yml |
traefik/dynamic/dashboards.yml |
/mnt/user/appdata/traefik/dynamic/dashboards.yml |
Pflicht-Workflow bei Aenderungen an Traefik Dynamic Config
- Datei im Git-Repo (
traefik/dynamic/) aendern - Commit + Push
- Datei manuell auf den Host kopieren
- Traefik laedt dynamic config automatisch neu
- Aenderung testen
Merksatz: Git-Commit allein reicht hier nicht. Ohne den manuellen Kopier-Schritt wirkt die Aenderung nicht.
Ausnahme: Authelia configuration.yml
Diese Datei wird von Komodo nicht automatisch deployed.
security/authelia/configuration.yml ist die Repo-Baseline fuer nicht geheime Einstellungen (Access-Control, Session, Storage-Struktur, Notifier, TOTP). Die produktive Host-Datei darf zusaetzlich OIDC-Clients und hostseitige Identity-Provider-Konfiguration enthalten. Secret-Werte und die User-Datenbank bleiben grundsaetzlich ausserhalb von Git.
| Git-Pfad | Host-Pfad (NAS) |
|---|---|
security/authelia/configuration.yml |
/mnt/user/appdata/authelia/config/configuration.yml |
Pflicht-Workflow bei Aenderungen an configuration.yml
- Datei im Git-Repo (
security/authelia/) aendern. - Commit + Push.
- Aenderung manuell in die Host-Datei mergen, OIDC-/Identity-Provider-Sektionen erhalten.
docker restart autheliaund Login-Smoke-Test auf einer ACL-betroffenen Domain.services/authelia-diff.sh(Default-Aufruf) mussexit 0liefern.
Automatische Drift-Erkennung
services/authelia-diff.sh vergleicht die access_control:-Sektion zwischen Repo-Baseline und Host-Datei. Der Posture-Check (services/posture-check/posture-check.sh) ruft das Skript als Check authelia_config_drift auf und meldet Drift als Warning via ntfy.
Konfigurierbare Variablen (Defaults sind das produktive Zielbild):
AUTHELIA_REPO_BASELINE— Pfad zur Repo-Datei auf dem Host, Default/mnt/user/services/homelab-infra/security/authelia/configuration.ymlAUTHELIA_HOST_CONFIG— Pfad zur produktiven Host-Datei, Default/mnt/user/appdata/authelia/config/configuration.ymlAUTHELIA_DIFF_SECTIONS— Komma-Liste der zu vergleichenden Top-Level-Sektionen, Defaultaccess_controlAUTHELIA_DIFF_SCRIPT— Pfad zum Diff-Skript fuer den Posture-Check, Default/mnt/user/services/homelab-infra/services/authelia-diff.shSKIP_AUTHELIA_DRIFT=1— Check im Posture-Check ueberspringen
Pflicht-Setup auf dem Host: Repo-Spiegel unter /mnt/user/services/homelab-infra/ (Read-only-Clone von Gitea Micha/homelab-infra, regelmaessig git pull --ff-only). Ohne Repo-Spiegel meldet der Check Warning, weil die Baseline-Datei fehlt — Critical wird der Check bewusst nicht.
Merksatz: Push allein reicht hier nicht. Ohne den manuellen Merge ins Host-Configfile wirkt die Aenderung nicht, und der Drift-Check wuerde Warning melden.
Secrets-Regeln
- Secrets liegen niemals im Repository
- Secrets liegen unter
/mnt/user/appdata/secrets/ - Secrets werden ueber Datei-Mounts mit
_FILEVariablen oder Komodo Stack Environment Variables eingebunden - Rechte:
chmod 600 - Secret-Namen und Pfade werden in
docs/SECRETS_MAP.mddokumentiert
Image-Versionierung
- Mutable Tags wie
latest,stable,releaseoder reine Major-Tags werden nach Moeglichkeit auf den aktuell laufenden Digest gepinnt. - Digest-Pinning friert den bekannten Laufzeitstand ein; es ist kein automatisches Upgrade.
- Echte Versions-Upgrades sind ein eigener, bewusster Aenderungsblock mit anschliessendem Test.
- Wenn der laufende Digest unbekannt ist, wird er zuerst am produktiven Container ausgelesen und erst danach im Repo festgeschrieben.
DNS-Regeln fuer Container
Nicht alle Container koennen externe DNS-Namen aufloesen. Standardmaessig nutzt Docker 127.0.0.11 als internen DNS-Resolver. In bestimmten Netzwerk-Setups schlaegt externe Namensaufloesung damit fehl (server misbehaving).
Regel
Container die externe Domains aufloesen muessen erhalten explizit:
dns:
- 1.1.1.1
- 8.8.8.8
Aktuell betroffen
| Service | Grund |
|---|---|
traefik |
ACME Let's Encrypt (acme-v02.api.letsencrypt.org) |
ddns-updater |
IP-Erkennung (ipify.org) + Cloudflare API |
Service-Removal-Checkliste
Wenn ein Stack endgueltig entfernt wird (Beispiele: Homepage am 2026-05-25, Uptime-Kuma am 2026-05-25, Jellyfin am 2026-05-25), muss in einem Aenderungsblock auch der gesamte Sicht-/Backup-Pfad nachgezogen werden, sonst entstehen "Tote-Pfad-Warnings", die erst Tage spaeter auftauchen.
Pflicht-Schritte vor dem Schliessen:
- Komodo: Stack stoppen, destroy, Stack-Eintrag loeschen.
- Gitea-Webhook fuer den Stack deaktivieren.
- Repo-Pfad per
git rmentfernen. - Appdata nach
/mnt/user/appdata/_archive/<name>-removed-YYYY-MM-DD/verschieben (14 Tage Karenz). - DNS-Eintrag im Cloudflare entfernen, sofern Public-Domain.
- Authelia ACL-Eintrag in
security/authelia/configuration.ymlund auf dem Host bereinigen. - Monitoring: Blackbox-Target in
monitoring/blackbox/blackbox.ymlentfernen, Cert-Check-Liste pruefen. - Borg-UI Source-Liste:
https://borg.kaleschke.info-> Repositoryappdata-critical-> Source Directories -> alle/local/appdata/<name>und ggf./local/<name>-Eintraege loeschen. Sonst kommen dailyHomelabBorgLastJobCompletedWithWarnings-Push-Nachrichten mitBackupFileNotFoundErrorim Logfile. docs/SERVICE_CATALOG.md,docs/REPO_MAP.md,HOMELAB_ARCHITECTURE_MASTER_V2.mdSektion 7.8 (Entfernt),docs/MIGRATION_LOG.mdnachziehen.
Wenn ein Stack webhook_enabled in Komodo hatte, zusaetzlich pruefen, ob der zugehoerige Gitea-Hook deaktiviert oder geloescht wurde.
Dokumentationspflicht
Nach jeder erfolgreichen Migration oder relevanten Aenderung muessen diese Dateien geprueft werden:
docs/MIGRATION_LOG.mddocs/SECRETS_MAP.mddocs/ROLLBACK.mddocs/SERVICES_RECOVERY.mdfalls/mnt/user/services, Gitea, Komodo oder Host-Automation betroffen sinddocs/HARDWARE_INVENTORY.mdunddocs/CAPACITY_AND_LIFECYCLE.mdfalls Hardware, Disks, Cache, RAM oder USV betroffen sinddocs/NETWORK_INVENTORY.mdunddocs/EXTERNAL_DEPENDENCIES.mdfalls Router, DNS, Tailscale, Portfreigaben oder Provider betroffen sindHOMELAB_ARCHITECTURE_MASTER_V2.mdfalls Architektur betroffen istdocs/GITOPS_DRIFT_RUNBOOK.mdfalls GitOps-/Komodo-/Runtime-Drift betroffen ist
Rollback-Regel
Jede Aenderung muss rueckrollbar sein. Vor jedem Deploy muss klar sein:
- wie der letzte funktionierende Zustand aussieht
- welcher Commit der letzte stabile Stand ist
- ob Datenpfade unveraendert bleiben
- wie der Dienst im Fehlerfall zurueckgenommen wird
Wenn Rollback nicht klar ist, wird nicht deployed.
Arbeitsregel fuer KI-Assistenten
Wenn mit einer KI gearbeitet wird, gilt immer:
Lies zuerst:
HOMELAB_ARCHITECTURE_MASTER_V2.mddocs/WORKFLOW.md- die betroffene Compose-Datei
- ggf.
docs/MIGRATION_LOG.md
Erst danach duerfen Aenderungen vorgeschlagen werden.
Merksatz
Erst syncen, dann aendern. Erst Git, dann Deploy. Kein Drift, kein Chaos.