Files

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 origin und 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

  1. origin/master in Gitea
  2. lokaler Clone auf dem Windows-PC
  3. Komodo-Deployments / Webhooks
  4. 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:

  1. Lokal synchronisieren
  2. Lokal aendern
  3. Commit erzeugen
  4. Push nach Gitea
  5. Komodo reagiert automatisch per Webhook
  6. Ergebnis testen
  7. 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:

  1. GitHub Desktop oeffnen
  2. Fetch origin
  3. wenn noetig Pull origin

Nach lokaler Arbeit:

  1. Aenderungen pruefen
  2. bei Compose-/Backup-/Restore-Aenderungen relevante manuelle Repo-Checks ausfuehren
    • ops/policy-checks/check_repo.ps1
    • ops/restore-tests/check-restore-freshness.ps1 oder gezielte Restore-Checks
  3. Commit mit sauberer Nachricht
  4. Push origin
  5. 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:

  1. GitHub Desktop oeffnen
  2. Fetch origin
  3. Pull origin
  4. 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:

  1. Stack in Komodo aus Gitea anlegen
  2. webhook_enabled in Komodo aktivieren
  3. passenden Gitea-Webhook fuer die aktuelle Stack-ID anlegen
  4. Gitea-Hook gegen http://komodo-core:9120/listener/github/stack/<stack-id>/deploy pruefen
  5. einen Push oder Test-Delivery ausloesen und last_status/Komodo-Deploy pruefen
  6. 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:

  1. Drift nicht ignorieren
  2. Drift sofort benennen
  3. entscheiden:
    • Repo an Realitaet anpassen
    • oder Realitaet an Repo zurueckfuehren
  4. erst danach weiterarbeiten

Pflichtcheck bei Drift-Verdacht

Vor jedem Reparaturversuch muessen die Ebenen getrennt geprueft werden:

  1. lokaler Clone
  2. Gitea origin/master
  3. Komodo Stack Workspace
  4. Docker Runtime
  5. 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:

  1. Hotfix nur wenn der Dienst sonst nicht funktioniert
  2. Aenderung sofort dokumentieren
  3. Aenderung danach ins Git-Modell ueberfuehren
  4. 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

  1. Datei im Git-Repo (traefik/dynamic/) aendern
  2. Commit + Push
  3. Datei manuell auf den Host kopieren
  4. Traefik laedt dynamic config automatisch neu
  5. 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

  1. Datei im Git-Repo (security/authelia/) aendern.
  2. Commit + Push.
  3. Aenderung manuell in die Host-Datei mergen, OIDC-/Identity-Provider-Sektionen erhalten.
  4. docker restart authelia und Login-Smoke-Test auf einer ACL-betroffenen Domain.
  5. services/authelia-diff.sh (Default-Aufruf) muss exit 0 liefern.

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.yml
  • AUTHELIA_HOST_CONFIG — Pfad zur produktiven Host-Datei, Default /mnt/user/appdata/authelia/config/configuration.yml
  • AUTHELIA_DIFF_SECTIONS — Komma-Liste der zu vergleichenden Top-Level-Sektionen, Default access_control
  • AUTHELIA_DIFF_SCRIPT — Pfad zum Diff-Skript fuer den Posture-Check, Default /mnt/user/services/homelab-infra/services/authelia-diff.sh
  • SKIP_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 _FILE Variablen oder Komodo Stack Environment Variables eingebunden
  • Rechte: chmod 600
  • Secret-Namen und Pfade werden in docs/SECRETS_MAP.md dokumentiert

Image-Versionierung

  • Mutable Tags wie latest, stable, release oder 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:

  1. Komodo: Stack stoppen, destroy, Stack-Eintrag loeschen.
  2. Gitea-Webhook fuer den Stack deaktivieren.
  3. Repo-Pfad per git rm entfernen.
  4. Appdata nach /mnt/user/appdata/_archive/<name>-removed-YYYY-MM-DD/ verschieben (14 Tage Karenz).
  5. DNS-Eintrag im Cloudflare entfernen, sofern Public-Domain.
  6. Authelia ACL-Eintrag in security/authelia/configuration.yml und auf dem Host bereinigen.
  7. Monitoring: Blackbox-Target in monitoring/blackbox/blackbox.yml entfernen, Cert-Check-Liste pruefen.
  8. Borg-UI Source-Liste: https://borg.kaleschke.info -> Repository appdata-critical -> Source Directories -> alle /local/appdata/<name> und ggf. /local/<name>-Eintraege loeschen. Sonst kommen daily HomelabBorgLastJobCompletedWithWarnings-Push-Nachrichten mit BackupFileNotFoundError im Logfile.
  9. docs/SERVICE_CATALOG.md, docs/REPO_MAP.md und HOMELAB_ARCHITECTURE_MASTER_V2.md Sektion 7.8 (Entfernt) nachziehen.

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/SECRETS_MAP.md
  • docs/ROLLBACK.md
  • docs/SERVICES_RECOVERY.md falls /mnt/user/services, Gitea, Komodo oder Host-Automation betroffen sind
  • docs/HARDWARE_INVENTORY.md und docs/CAPACITY_AND_LIFECYCLE.md falls Hardware, Disks, Cache, RAM oder USV betroffen sind
  • docs/NETWORK_INVENTORY.md und docs/EXTERNAL_DEPENDENCIES.md falls Router, DNS, Tailscale, Portfreigaben oder Provider betroffen sind
  • HOMELAB_ARCHITECTURE_MASTER_V2.md falls Architektur betroffen ist
  • docs/GITOPS_DRIFT_RUNBOOK.md falls 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:

  1. HOMELAB_ARCHITECTURE_MASTER_V2.md
  2. docs/WORKFLOW.md
  3. die betroffene Compose-Datei
  4. die relevante Betriebsdoku aus docs/README.md

Erst danach duerfen Aenderungen vorgeschlagen werden.


Merksatz

Erst syncen, dann aendern. Erst Git, dann Deploy. Kein Drift, kein Chaos.