Files
homelab-infra/HOMELAB_ARCHITECTURE_MASTER_V2.md
T
Micha bcb2bf81a8 Document Authelia without Redis session backend
Document Authelia without Redis session backend
2026-05-04 19:51:44 +02:00

31 KiB

HOMELAB_ARCHITECTURE — MASTER v2

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-04-17 | Aktueller Schwerpunkt: GitOps / Doku-Synchronisierung / Reproduzierbare Deployments


Inhaltsverzeichnis

  1. Systemüberblick
  2. Architektur-Prinzipien
  3. Finales Netzwerk-Zielbild
  4. Zugangsmodell: Traefik vs. Tailscale
  5. Globale Sicherheitsregeln
  6. Einordnungsschema für neue Container
  7. Container-Zielbild (vollständig)
  8. Traefik-Label-Standard
  9. Historische Migration (abgeschlossen)
  10. Bekannte Ausnahmen und Begründungen
  11. Projektorganisation und Arbeitsmodus
  12. Nutzung mit KI / Kontext-Regel
  13. Betriebserfahrungen und Entscheidungs-Log

1. Systemüberblick

Eigenschaft Wert
Host-OS Unraid
Hostname Kallilabcore
Reverse Proxy Traefik v3 (Service-Routing via Docker-Labels, File-Provider fuer Middlewares, TLS und Dashboards)
VPN / Remote-Zugang Tailscale (tailscale, host-Netz, Git-Stack)
DNS-Stack AdGuard Home (dns_net + frontend_net) → Unbound (dns_net)
Basis-Domain kaleschke.info
TLS Let's Encrypt via Cloudflare DNS Challenge
Certresolver le
Compose-Standard Komodo (GitOps, Stack aus Gitea)
Legacy Portainer CE entfernt; Komodo ist alleiniger Stack-Manager
Homelab-Compose-Pfad /mnt/user/services/homelab/
Secrets-Pfad /mnt/user/appdata/secrets/
Grundsatz Keine neuen Dockerman-Einzelcontainer

2. Architektur-Prinzipien

P1 — Traefik ist der einzige öffentliche HTTP(S)-Einstiegspunkt

Kein Webdienst veröffentlicht finale direkte Host-Ports außer traefik selbst. Begründete Ausnahmen: gitea-SSH (Port 222), AdGuard Home (Port 53/DNS + 8082/Admin), Tailscale, Plex-Media-Server und influxdb3-core Port 8181 als LAN-only Writer-Endpunkt fuer Home Assistant.

P2 — Das Setup bleibt bewusst einfach: frontend_net + backend_net + app-interne Netze

  • frontend_net = Proxy-/Web-Netz
  • backend_net = intern für DB/Cache/App-Kommunikation
  • zusätzliche Netze nur app-intern, wenn technisch nötig (mealie_mealie_internal, immich_default, dns_net)

Es gibt keine künstlichen globalen Zusatznetze wie admin_net, monitoring_net oder media_net.

P3 — Datenbanken gehören nie ins frontend_net

Postgres, Redis und ähnliche Dienste laufen ausschließlich in backend_net oder einem eigenen internen Compose-Netz.

P4 — Admin-UIs sind nicht öffentlich

filebrowser, scrutiny, UptimeKuma, code-server, Traefik-Dashboard, backrest und borg-ui sind standardmaessig Tailscale-only oder hinter Traefik mit zentraler Middleware abgesichert. Komodo ist die dokumentierte Ausnahme und bleibt bewusst bei nativer Authentifizierung ohne pauschal vorgeschaltete ForwardAuth-Middleware.

P5 — Compose-first

Alle produktiven Container werden als Compose verwaltet. Bestehende Dockerman-/Ad-hoc-Container werden schrittweise migriert.

P6 — Secrets nie im Klartext

Passwörter, Tokens und API-Keys gehören in Secret-Dateien unter /mnt/user/appdata/secrets/ oder als Komodo Stack Environment Variables mit ${VARIABLE} in der Compose.

P7 — restart: unless-stopped ist Pflichtstandard

Jeder produktive Container nutzt restart: unless-stopped, außer eine Ausnahme ist dokumentiert.

P8 — Least Privilege

  • security_opt: ["no-new-privileges:true"] standardmäßig ergänzen
  • privileged: true nur mit dokumentierter Begründung
  • Docker-Socket standardmäßig vorsichtig behandeln; Komodo ist dokumentierte Ausnahme

3. Finales Netzwerk-Zielbild

3.1 Netz-Logik

Netzwerk Typ Zweck Status
frontend_net bridge, external einziges Traefik-/Web-Netz Standard
backend_net bridge, internal: true interne App-/DB-/Cache-Kommunikation Standard
dns_net bridge Resolver-Schicht: AdGuard Home + Unbound bleibt
mealie_mealie_internal bridge, internal: true internes Netz nur für mealie + mealie-postgres umgesetzt
immich_default Compose-intern, internal: true internes Immich-Netz umgesetzt
nextcloud_internal bridge, internal: true internes Netz nur fuer nextcloud + nextcloud-postgres + nextcloud-redis vorbereitet
grafana_influx_internal Compose-intern, internal: true interne Grafana-zu-InfluxDB-Kommunikation umgesetzt
grafana_influx_lan Compose-intern, bridge nicht-oeffentliches Zusatznetz nur fuer Docker Host-Port-Publishing von InfluxDB 8181 umgesetzt
host host nur für echte Sonderfälle begründet

3.2 Finales Diagramm (vereinfacht)

Internet
│
▼
traefik (80/443)
│
└── frontend_net
    ├── öffentliche Apps (vaultwarden, mealie, paperless, immich, gitea, ntfy, mail-archiver, nextcloud)
    ├── geschützte UIs mit Middleware (homepage, paperless-gpt, uptime-kuma, filebrowser, scrutiny, code-server, backrest, borg-ui, glances, speedtest, bentopdf, grafana)
    ├── Admin-UI mit nativer Auth (komodo)
    └── Dienste mit Internetbedarf ohne öffentliche UI (ddns-updater)

backend_net (internal: true)
├── postgresql17
├── Redis
├── mail-archiver
└── paperless-ngx

dns_net
├── AdGuard Home (+ frontend_net, feste IP 172.23.0.3)
└── unbound

App-interne Netze
├── mealie_mealie_internal (internal: true) ✅
├── immich_default (internal: true) ✅
├── nextcloud_internal (internal: true) ✅
├── grafana_influx_internal (internal: true)
└── grafana_influx_lan (Bridge fuer LAN-Port-Publishing, keine Traefik-Route)

Host-Sonderfälle
├── tailscale
└── Plex-Media-Server


4. Zugangsmodell: Traefik vs. Tailscale

4.1 Öffentlich über Traefik

Diese Dienste sind über echte *.kaleschke.info-Domains erreichbar:

  • vaultwarden — vault.kaleschke.info
  • mealie — mealie.kaleschke.info
  • paperless-ngx — paperless.kaleschke.info
  • ntfy — ntfy.kaleschke.info
  • gitea (Web) — git.kaleschke.info
  • immich_server — immich.kaleschke.info
  • mail-archiver — mail.kaleschke.info
  • nextcloud — cloud.kaleschke.info

4.2 Nicht öffentlich / nur Tailscale oder Traefik + Middleware

Diese Dienste sind keine Public Apps:

  • Komodo — komodo.kaleschke.info (Traefik, aber bewusst ohne zentrale Middleware; native Auth bleibt aktiv)
  • UptimeKuma — uptime.kaleschke.info (Middleware)
  • filebrowser — files.kaleschke.info (Middleware)
  • scrutiny — scrutiny.kaleschke.info (Middleware)
  • code-server — Traefik + Middleware
  • backrest — Traefik + Middleware
  • borg-ui — borg.kaleschke.info (Middleware)
  • homepage — home.kaleschke.info (Middleware)
  • paperless-gpt — paperless-gpt.kaleschke.info (Middleware)
  • glances — glances.kaleschke.info (Middleware)
  • speedtest-tracker — speedtest.kaleschke.info (Middleware)
  • bentopdf — pdf.kaleschke.info (Middleware)
  • grafana — grafana.kaleschke.info (Middleware)
  • Traefik-Dashboard
  • AdGuard Home — Port 8082 direkt auf die Admin-UI (80 im Container), kein Traefik, nur LAN-Zugang

4.3 Regel

Wenn ein Dienst im frontend_net hängt, heißt das nicht automatisch öffentlich. Admin-Dienste dürfen im frontend_net liegen, wenn:

  • Traefik sie routet
  • zentrale Middleware aktiv ist
  • keine direkten Host-Ports bestehen
  • Zugriff durch Tailscale bzw. Auth begrenzt ist

Komodo ist hiervon die dokumentierte Ausnahme: Traefik ja, aber keine pauschale ForwardAuth-Middleware, damit Webhooks, API und Periphery-Kommunikation nicht versehentlich beeintraechtigt werden.


5. Globale Sicherheitsregeln

  1. Keine produktiven Dienste im Docker-Default-bridge
  2. Keine direkten Host-Ports für Web-UIs außer dokumentierte Ausnahmen
  3. restart: unless-stopped als Standard
  4. Secrets als Datei / _FILE oder Komodo Stack Environment Variables mit ${VAR}
  5. no-new-privileges:true ergänzen, wo praktikabel
  6. traefik.docker.network=frontend_net immer explizit setzen
  7. Admin- und interne Web-Dienste standardmaessig mit zentraler Middleware absichern (authelia@file,secure-headers@file oder dokumentierte Ausnahme)
  8. Placeholder-Domains (yourdomain.tld) sind verboten
  9. privileged: true nur mit Begründung
  10. Volume-Mounts so klein und so read-only wie möglich
  11. Neue Dienste nur via Compose / Git-Stack
  12. Änderungen immer gegen dieses Dokument prüfen

6. Einordnungsschema für neue Container

Schritt 1 — Hat der Dienst eine Web-UI?

  • Jafrontend_net
  • Nein → weiter zu Schritt 2

Schritt 2 — Braucht der Dienst externe Internetverbindungen?

  • Jafrontend_net (auch ohne Web-UI)
  • Nein → weiter zu Schritt 3

Schritt 3 — Braucht der Dienst eine DB / Redis / interne Backends?

  • Ja → zusätzlich backend_net oder eigenes app-internes Netz
  • Nein → nur das funktional nötige Netz

Schritt 4 — Ist es eine Datenbank oder ein Cache?

  • Ja → niemals frontend_net, nur backend_net oder internes Compose-Netz

Schritt 5 — Ist es ein Admin-/Monitoring-Dienst?

  • Ja → wenn Web-UI vorhanden trotzdem frontend_net, aber nur mit Middleware und ohne direkte Portfreigabe

Schritt 6 — Braucht der Dienst Host-/Discovery-/L2-Sicht?

  • Jahost nur mit dokumentierter Begründung

Schritt 7 — Braucht die App ein eigenes internes App-Netz?

  • Ja → Compose-internes Netz mit internal: true

7. Container-Zielbild (vollständig)

Legende Status:

  • = umgesetzt und in Git-Stack
  • ✅ (Dockerman) = Traefik/Netz korrekt konfiguriert, noch kein Git-Stack
  • = noch zu migrieren / zu korrigieren
  • ⚠️ Legacy = läuft, wird abgelöst
  • = entfernt

7.1 Infrastruktur / Core

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
traefik frontend_net, backend_net öffentlich 80/443 zentraler Ingress, Service-Routing via Docker-Labels
AdGuard Home dns_net (172.23.0.3), frontend_net Port 53 DNS direkt, Port 8082 Admin (LAN) DNS-Server + Upstream zu unbound; kein Traefik (DNS-Sonderfall) Admin-Port per Traefik + Middleware absichern (Block F)
unbound dns_net intern Upstream-Resolver für AdGuard, isoliert
ddns-updater frontend_net intern Cloudflare DNS API; bleibt in frontend_net Dokumentierte Ausnahme
tailscale host VPN-Zugang Git-Stack (host-services/tailscale/) TS_USERSPACE/privileged später prüfen
backrest frontend_net, backend_net Traefik + Middleware produktiver Backup-Admin-Dienst breite Mounts bewusst dokumentieren
homepage frontend_net Traefik + Middleware geschuetztes Start-Dashboard via home.kaleschke.info

7.2 Sicherheit / Identity

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
vaultwarden frontend_net Traefik kein Host-Port, ADMIN_TOKEN_FILE
authelia frontend_net, backend_net Traefik via auth.kaleschke.info aktiver ForwardAuth-Provider, Secrets via _FILE, PostgreSQL Storage; bewusst ohne Redis-Session-Backend

7.3 Datenbanken / Caches

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
postgresql17 backend_net intern kein Host-Port, POSTGRES_PASSWORD_FILE
Redis backend_net intern intern-only Cache optional named volume
mealie-postgres mealie_mealie_internal intern isoliert, nie frontend_net
immich_postgres immich_default intern intern-only
immich_redis immich_default intern intern-only anonymes Volume → named volume
nextcloud-postgres nextcloud_internal intern app-eigene Nextcloud-Datenbank mit _FILE-Secret
nextcloud-redis nextcloud_internal intern app-eigener Cache fuer File Locking / Sessions

7.4 Öffentliche Apps

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
paperless-ngx frontend_net, backend_net Traefik aktiv via paperless.kaleschke.info
mail-archiver frontend_net, backend_net Traefik aktiv via mail.kaleschke.info; IMAP-Abruf + DB-Zugang
mealie frontend_net, mealie_mealie_internal Traefik sauber getrennte App/DB-Struktur
ntfy frontend_net Traefik aktiv via ntfy.kaleschke.info, Git-Stack
gitea frontend_net Traefik + SSH-Port 222 Web via Traefik, SSH direkt gebunden
immich_server immich_default, frontend_net Traefik aktiv via immich.kaleschke.info
immich_machine_learning immich_default intern bleibt intern
nextcloud frontend_net, nextcloud_internal Traefik aktiv via cloud.kaleschke.info, nativer Nextcloud-Login, WebDAV/CardDAV faehig CalDAV/CardDAV-Redirect via Traefik-Labels

7.5 Admin / Operations

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
komodo frontend_net Traefik, native Auth primaerer GitOps-Stack-Manager bewusste Ausnahme: keine pauschale ForwardAuth-Middleware vor UI/API/Webhooks/Periphery
code-server frontend_net Traefik + Middleware PASSWORD_FILE aktiv
PortainerCE entfernt - - 2026-03-29 abgeschaltet historisch; nicht mehr deployen
filebrowser frontend_net Traefik + Middleware aktiv via files.kaleschke.info Mounts einschränken (Block F)
borg-ui frontend_net Traefik + Middleware produktiver Borg-/Restore-Dienst; /local/secrets ist bewusst Teil des Restore-Scopes BorgBase-Repo und Key laufend pflegen
paperless-gpt frontend_net Traefik + Middleware aktiv via paperless-gpt.kaleschke.info
bentopdf vorbereitet frontend_net Traefik + Middleware PDF-Tooling via pdf.kaleschke.info; browserseitige Verarbeitung, COOP/COEP fuer Office-Konvertierung Deploy und fachliche Abnahme offen

7.6 Monitoring / Status

Container Status Soll-Netz(e) Finaler Zugang Finaler Sollzustand Offene Punkte
UptimeKuma frontend_net Traefik + Middleware aktiv via uptime.kaleschke.info
glances frontend_net Traefik + Middleware aktiv via glances.kaleschke.info
scrutiny frontend_net Traefik + Middleware aktiv via scrutiny.kaleschke.info, Git-Stack privileged später prüfen
speedtest-tracker frontend_net Traefik + Middleware aktiv via speedtest.kaleschke.info
grafana frontend_net, grafana_influx_internal Traefik + Middleware aktiv via grafana.kaleschke.info, InfluxDB-Datenquelle provisioniert Wetter-/HA-Dashboard aufbauen
influxdb3-core grafana_influx_internal, grafana_influx_lan + LAN-Bind LAN-Port nur fuer interne Writer InfluxDB 3 Core fuer Metriken; keine Traefik-/Public-Freigabe; Port 8181 nur via INFLUXDB_BIND_IP HA-Write-Token und Sensor-Export finalisieren

7.7 Noch offene Sonderfälle

Container Status Ziel
Plex-Media-Server Dockerman Compose-Migration, host-Netz bleibt (Discovery)

7.8 Entfernte Container

Container Entfernt am Begründung
scanopy-server 2026-03-26 nicht genutzt, durch paperless-ngx ersetzt
scanopy-postgres 2026-03-26 zusammen mit scanopy entfernt
scanopy-daemon 2026-03-26 zusammen mit scanopy entfernt
diun 2026-03-28 Update-Monitoring via Komodo; Stack + Netz diun_diun_default + Repo-Eintrag entfernt
binhex-official-pihole 2026-03-28 ersetzt durch AdGuard Home + Unbound
gotify 2026-03-28 nicht mehr aktiv; Push-Notifications via ntfy abgedeckt
Dozzle 2026-03-28 nicht mehr aktiv
dashdot 2026-03-28 nicht mehr aktiv
netdata 2026-03-28 nicht mehr aktiv
netalertx 2026-03-28 nicht mehr aktiv
luckyBackup 2026-03-28 nicht mehr aktiv; Backup via backrest
Stash 2026-03-28 nicht mehr aktiv
PortainerCE 2026-03-29 abgeschaltet; Komodo ist alleiniger Stack-Manager
beszel nicht dokumentiert bereits entfernt; nicht mehr Teil des Zielbilds
beszel-agent nicht dokumentiert bereits entfernt; nicht mehr Teil des Zielbilds

8. Traefik-Label-Standard

Jeder Dienst mit Traefik-Routing nutzt dieses Muster:

labels:
  - traefik.enable=true
  - traefik.docker.network=frontend_net
  - traefik.http.routers.<name>.rule=Host(`<subdomain>.kaleschke.info`)
  - traefik.http.routers.<name>.entrypoints=websecure
  - traefik.http.routers.<name>.tls=true
  - traefik.http.routers.<name>.tls.certresolver=le
  - traefik.http.services.<name>.loadbalancer.server.port=<interner-port>

Zusatz fuer Admin-Dienste (Standard)

  - traefik.http.routers.<name>.middlewares=authelia@file,secure-headers@file

Regeln

  • traefik.docker.network immer explizit auf frontend_net
  • keine yourdomain.tld-Platzhalter
  • certresolver immer le
  • tls=true immer explizit setzen
  • wenn Traefik aktiv ist, werden direkte Host-Ports entfernt
  • Admin-Dienste standardmaessig nicht ohne Middleware veroeffentlichen
  • Das Traefik-Dashboard nutzt ebenfalls authelia@file; dokumentierte Ausnahmen wie Komodo bleiben moeglich
  • File-Provider nur noch für: middlewares.yml, tls.yml, dashboards.yml — keine Service-Routen mehr via File-Provider
  • dokumentierte Ausnahmen muessen in Abschnitt 10 begruendet werden

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

10. Bekannte Ausnahmen und Begründungen

Container Ausnahme Begründung
traefik Host-Ports 80/443 zentraler Reverse Proxy
tailscale host VPN-Zugang; Umstellung nur kontrolliert möglich
AdGuard Home Port 53 (TCP/UDP) direkt + Port 8082 auf Container-Port 80 DNS benötigt direkten Port 53; kein HTTP-Proxy für DNS möglich
Plex-Media-Server host Discovery / mDNS / Plex GDM
scrutiny privileged: true SMART-Datenzugriff auf Laufwerke
Komodo Docker-Socket Zugriff Stack-Deployments benötigen Socket
Komodo keine pauschale zentrale Middleware Webhooks (/listener), API und Periphery-WebSocket (/ws/periphery) sollen nicht durch vorgeschaltete ForwardAuth gebrochen werden
gitea SSH-Port 222 direkt gebunden Git-SSH-Zugang; kein HTTP-Proxy für SSH möglich
ddns-updater bleibt in frontend_net statt backend_net braucht Cloudflare-API-Zugang; backend_net ist internal: true
mail-archiver frontend_net + backend_net braucht Internetzugang für IMAP-Abruf (GMX, Gmail) und DB-Zugang
traefik/dynamic/* manueller Host-Sync trotz GitOps File-Provider bleibt bewusst fuer middlewares.yml, tls.yml und dashboards.yml; Komodo deployed diese Dateien nicht automatisch
nextcloud keine zentrale ForwardAuth-Middleware Nextcloud bringt eigene Auth, Clients und WebDAV/CardDAV-Endpunkte mit; Traefik bleibt Reverse Proxy, Auth bleibt app-nativ
influxdb3-core Host-Port 8181 auf LAN-IP Home Assistant laeuft in einer VM ausserhalb des Compose-Netzes und muss Metriken schreiben koennen; keine Traefik-Route, kein frontend_net, Zugriff nur ueber Token und LAN-IP INFLUXDB_BIND_IP

11. Projektorganisation und Arbeitsmodus

11.1 Unser Arbeitsprinzip

Dieses Projekt wird heute nicht mehr sprintweise im Dokument gesteuert, sondern über einen stabilen GitOps-Betrieb.

11.2 Operativer Ablauf

  1. Zielbild prüfen
  2. lokal synchronisieren
  3. gezielt ändern
  4. Commit + Push
  5. Komodo-Webhook und Ergebnis prüfen
  6. Dokumentation nachziehen

11.3 Regel für jede Änderung

  1. Zielbild in diesem Dokument prüfen
  2. nur den betroffenen Bereich anfassen
  3. Änderung lokal vorbereiten
  4. nach Gitea pushen
  5. automatische Reaktion von Komodo beachten
  6. testen
  7. dokumentieren

11.4 Source-of-Truth-Hierarchie

  1. Gitea Online (origin/master)
  2. lokaler Clone / GitHub Desktop
  3. Compose-Dateien im Git-Repo
  4. Komodo als Deploy-Consumer
  5. operative Checklisten und Notizen

11.5 Operativer Git-Workflow

  • Gitea Online ist der verbindliche Sollzustand.
  • Lokal wird standardmäßig über GitHub Desktop gearbeitet.
  • Komodo deployt aus Gitea und ist kein Bearbeitungsort.
  • Webhooks sind aktiv: Ein Push kann unmittelbar einen Komodo-Deploy auslösen.
  • Wenn online in Gitea editiert wurde, muss vor der nächsten lokalen Änderung zuerst Fetch origin und danach Pull origin erfolgen.

12. Nutzung mit KI / Kontext-Regel

Wenn mit einer KI gearbeitet wird, gilt immer:

„Lies zuerst HOMELAB_ARCHITECTURE_MASTER_V2.md, dann beantworte meine Frage."

Damit ist sofort klar:

  • welche Netze Standard sind
  • welche Container wohin gehören
  • welche Dienste öffentlich sein dürfen
  • welche Dienste nur intern/VPN-only sind
  • welche Migrationen noch offen sind
  • welche Ausnahmen bewusst dokumentiert sind

13. Betriebserfahrungen und Entscheidungs-Log

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.

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 Host-Port 8082 auf Container-Port 80 — Traefik-Absicherung ausstehend (Block F)
  • 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.

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 Grafana/InfluxDB vorbereitet (2026-04-30)

  • 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.
  • grafana wird als geschuetztes Monitoring-UI unter grafana.kaleschke.info betrieben.
  • 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 influxdb3-core zusaetzlich zum internen Grafana-Netz grafana_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.

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 bleibt shared Cache fuer Dienste wie Paperless, ist aber keine Authelia-Abhaengigkeit.

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. Aktuell via Traefik unter mail.kaleschke.info geroutet.

Netzwerk-Standard für Apps mit Datenbanken

  • App → frontend_net + internes Netzwerk
  • Datenbank → nur internes Netzwerk (internal: true)

Beispiel (Mealie): mealiefrontend_net + mealie_mealie_internal, mealie-postgres → nur mealie_mealie_internal.


Schlussformel

Dieses Dokument ist keine lose Notiz, sondern das operative Masterdokument für die Docker- und Zugriffsarchitektur des Homelabs.

Zielbild in einem Satz: frontend_net für Web-UIs und Dienste mit Internetbedarf, backend_net für interne Backends, app-interne Netze nur wenn technisch nötig, Tailscale für Remote-Admin-Zugriff, Traefik als einziger Web-Einstieg (Service-Routing via Docker-Labels, File-Provider nur für zentrale Dynamic-Config), Komodo als GitOps-Stack-Manager, AdGuard Home + Unbound für DNS, keine produktiven Container im Docker-Default-bridge.