Dateien nach "/" hochladen
This commit is contained in:
@@ -0,0 +1,557 @@
|
||||
# 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.
|
||||
|
||||
---
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
1. [Systemüberblick](#1-systemüberblick)
|
||||
2. [Architektur-Prinzipien](#2-architektur-prinzipien)
|
||||
3. [Finales Netzwerk-Zielbild](#3-finales-netzwerk-zielbild)
|
||||
4. [Zugangsmodell: Traefik vs. Tailscale](#4-zugangsmodell-traefik-vs-tailscale)
|
||||
5. [Globale Sicherheitsregeln](#5-globale-sicherheitsregeln)
|
||||
6. [Einordnungsschema für neue Container](#6-einordnungsschema-für-neue-container)
|
||||
7. [Container-Zielbild (vollständig)](#7-container-zielbild-vollständig)
|
||||
8. [Traefik-Label-Standard](#8-traefik-label-standard)
|
||||
9. [Migrationsstrategie (Blöcke A–F)](#9-migrationsstrategie-blöcke-a-f)
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## 1. Systemüberblick
|
||||
|
||||
| Eigenschaft | Wert |
|
||||
|---|---|
|
||||
| Host-OS | Unraid |
|
||||
| Hostname | Kallilabcore |
|
||||
| Reverse Proxy | Traefik v3 |
|
||||
| VPN / Remote-Zugang | Tailscale (`Tailscale-Docker`, host-Netz) |
|
||||
| DNS-Stack | Pi-hole (host) → Unbound (`dns_net`) |
|
||||
| Basis-Domain | `kaleschke.info` |
|
||||
| TLS | Let's Encrypt via Cloudflare DNS Challenge |
|
||||
| Certresolver | `le` |
|
||||
| Compose-Standard | Unraid Compose Manager |
|
||||
| Zusatz-Tool | Portainer als Verwaltungs-UI |
|
||||
| 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 final direkte Host-Ports außer `traefik` selbst.
|
||||
Begründete Ausnahmen: `gitea`-SSH, `Plex-Media-Server`, `binhex-official-pihole`, `Tailscale-Docker`.
|
||||
|
||||
### P2 — Das Setup bleibt bewusst einfach: `frontend_net` + `backend_net` + app-interne Netze
|
||||
Die Quellenlage für Homelabs mit Traefik spricht für ein simples 2-Netz-Modell:
|
||||
- `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_internal`, `immich_default`, `scanopy_scanopy`, `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
|
||||
Portainer, Dozzle, filebrowser, scrutiny, UptimeKuma, dashdot, code-server, luckyBackup, Traefik-Dashboard, netdata, Glances und netalertx sind standardmäßig **Tailscale-only** oder hinter Traefik **mit zentraler Middleware** abgesichert.
|
||||
|
||||
### 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 in `_FILE`-Variablen.
|
||||
Ziel: kein sensibles Secret mehr sichtbar in `docker inspect`.
|
||||
|
||||
### 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
|
||||
- `read_only: true` und Non-Root nur nach getesteter Image-Kompatibilität
|
||||
- Docker-Socket standardmäßig vorsichtig behandeln; **PortainerCE ist eine 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 für `unbound` | bleibt |
|
||||
| `mealie_internal` | bridge, `internal: true` | internes Netz nur für `mealie` + `mealie-postgres` | Ziel |
|
||||
| `immich_default` | Compose-intern | internes Immich-Netz | bleibt |
|
||||
| `scanopy_scanopy` | Compose-intern | internes Scanopy-Netz | bleibt |
|
||||
| `diun_default` | Compose-intern | Compose-Netz für diun | bleibt, zusätzlich Join zu `frontend_net` |
|
||||
| `host` | host | nur für echte Sonderfälle | begründet |
|
||||
|
||||
### 3.2 Finales Diagramm (vereinfacht)
|
||||
|
||||
```text
|
||||
Internet
|
||||
│
|
||||
▼
|
||||
traefik (80/443)
|
||||
│
|
||||
└── frontend_net
|
||||
├── öffentliche Apps
|
||||
├── Admin-UIs mit Middleware
|
||||
└── interne Web-UIs für Tailscale-only
|
||||
|
||||
backend_net (internal: true)
|
||||
├── postgresql17
|
||||
├── Redis
|
||||
├── mail-archiver
|
||||
└── paperless / andere Backends
|
||||
|
||||
App-interne Netze
|
||||
├── mealie_internal
|
||||
├── immich_default
|
||||
└── scanopy_scanopy
|
||||
|
||||
Host-Sonderfälle
|
||||
├── Tailscale-Docker
|
||||
├── binhex-official-pihole
|
||||
├── Plex-Media-Server
|
||||
├── netdata
|
||||
├── Glances
|
||||
└── netalertx
|
||||
```
|
||||
|
||||
### 3.3 Architekturentscheidung (final)
|
||||
**Wir bleiben final bei wenigen Netzen.**
|
||||
Das ist bewusst näher an aktuellen Homelab-Traefik-Setups als ein künstlich übersegmentiertes Docker-Netzmodell.
|
||||
Trennung erfolgt primär über:
|
||||
- Traefik
|
||||
- Auth-/Security-Middlewares
|
||||
- Tailscale
|
||||
- kein direktes Port-Publishing
|
||||
- app-interne Netze
|
||||
- Host-Sonderfälle nur mit Begründung
|
||||
|
||||
---
|
||||
|
||||
## 4. Zugangsmodell: Traefik vs. Tailscale
|
||||
|
||||
### 4.1 Öffentlich über Traefik
|
||||
Diese Dienste dürfen final über echte `*.kaleschke.info`-Domains erreichbar sein:
|
||||
|
||||
- `homepage`
|
||||
- `vaultwarden`
|
||||
- `mealie`
|
||||
- `paperless-ngx`
|
||||
- `gotify`
|
||||
- `gitea` (Web)
|
||||
- `immich_server`
|
||||
- optional `mail-archiver`
|
||||
- optional `backrest`
|
||||
- optional `Stash` (nur wenn bewusst gewünscht)
|
||||
|
||||
### 4.2 Nicht öffentlich / nur Tailscale oder Traefik + Middleware
|
||||
Diese Dienste sind **keine Public Apps**:
|
||||
|
||||
- `PortainerCE`
|
||||
- `Dozzle`
|
||||
- `UptimeKuma`
|
||||
- `dashdot`
|
||||
- `filebrowser`
|
||||
- `scrutiny`
|
||||
- `luckyBackup`
|
||||
- `code-server`
|
||||
- `scanopy-server`
|
||||
- `Traefik-Dashboard`
|
||||
- `netdata`
|
||||
- `Glances`
|
||||
- `netalertx`
|
||||
|
||||
### 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 zusätzlich durch Tailscale bzw. Auth begrenzt ist
|
||||
|
||||
---
|
||||
|
||||
## 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`
|
||||
5. `no-new-privileges:true` ergänzen, wo praktikabel
|
||||
6. `traefik.docker.network=frontend_net` immer explizit setzen
|
||||
7. Admin-Dienste immer mit `dashboard-auth@file,secure-headers@file`
|
||||
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 Manager / YAML
|
||||
12. Änderungen immer gegen dieses Dokument prüfen
|
||||
|
||||
---
|
||||
|
||||
## 6. Einordnungsschema für neue Container
|
||||
|
||||
### Schritt 1 — Hat der Dienst eine Web-UI?
|
||||
- **Ja** → `frontend_net`
|
||||
- **Nein** → weiter zu Schritt 2
|
||||
|
||||
### Schritt 2 — 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 3 — Ist es eine Datenbank oder ein Cache?
|
||||
- **Ja** → niemals `frontend_net`, nur `backend_net` oder internes Compose-Netz
|
||||
|
||||
### Schritt 4 — Ist es ein Admin-/Monitoring-Dienst?
|
||||
- **Ja** → wenn Web-UI vorhanden trotzdem `frontend_net`, aber nur mit:
|
||||
- Middleware
|
||||
- keiner direkten Portfreigabe
|
||||
- Tailscale-only-Charakter
|
||||
|
||||
### Schritt 5 — Braucht der Dienst Host-/Discovery-/L2-Sicht?
|
||||
- **Ja** → `host` nur mit dokumentierter Begründung
|
||||
- **Nein** → kein `host`
|
||||
|
||||
### Schritt 6 — Braucht die App ein eigenes internes App-Netz?
|
||||
- **Ja** → Compose-internes Netz mit `internal: true`
|
||||
- **Nein** → kein weiteres Netz anlegen
|
||||
|
||||
### Kurzregel
|
||||
- **UI** → `frontend_net`
|
||||
- **DB/Cache** → `backend_net`
|
||||
- **Spezialfall** → app-internes Netz
|
||||
- **Host-Zugriff** → nur dokumentierte Ausnahme
|
||||
|
||||
---
|
||||
|
||||
## 7. Container-Zielbild (vollständig)
|
||||
|
||||
Legende Status:
|
||||
- `✅` = bereits weitgehend passend
|
||||
- `⏳` = noch zu migrieren / zu korrigieren
|
||||
|
||||
### 7.1 Infrastruktur / Core
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `traefik` | ✅ | `frontend_net`, `backend_net` | öffentlich | zentraler Ingress, 80/443 direkt | Middleware-File-Provider sauber pflegen |
|
||||
| `homepage` | ✅ | `frontend_net` | Traefik | öffentliche Startseite | — |
|
||||
| `ddns-updater` | ⏳ | `backend_net` | intern | kein Grund für `frontend_net` | aus `frontend_net` raus |
|
||||
| `Tailscale-Docker` | ⏳ | `host` | VPN-Zugang | bleibt Host-Sonderfall | `restart` fixen; `TS_USERSPACE`/`privileged` später prüfen, nicht als Quick Win |
|
||||
| `binhex-official-pihole` | ⏳ | `host` | LAN DNS / intern | bleibt Host-Sonderfall | `restart` fixen |
|
||||
| `unbound` | ✅ | `dns_net` | intern | Resolver bleibt isoliert | — |
|
||||
| `backrest` | ⏳ | `frontend_net`, `backend_net` | Traefik oder intern | UI via Traefik, Repo intern | `traefik.docker.network` auf `frontend_net`; DNS-Hardcoding entfernen; Mounts straffen |
|
||||
| `diun` | ⏳ | `diun_default`, `frontend_net` | intern | braucht `frontend_net`, um `gotify` zu erreichen | Gotify-Endpoint per Container-Name |
|
||||
| `theme-park` | ⏳ | `frontend_net` oder rein intern | intern oder Traefik | nur veröffentlichen, wenn wirklich genutzt | Placeholder-Labels bereinigen |
|
||||
| `scanopy-daemon` | ⏳ | `host`, `scanopy_scanopy` falls nötig | intern | Host-naher Sonderfall | Privileged nur dokumentiert belassen oder später testen |
|
||||
|
||||
### 7.2 Sicherheit / Identity
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `vaultwarden` | ⏳ | `frontend_net` | Traefik | keine Host-Ports, kein `bridge`, Secret-Datei | `ADMIN_TOKEN`-Bug fixen; Port 4743 entfernen; Compose-Migration |
|
||||
|
||||
### 7.3 Datenbanken / Caches
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `postgresql17` | ⏳ | `backend_net` | intern | keine Host-Ports, kein `bridge` | Port 5432 entfernen; Secret-Datei; Compose-Migration |
|
||||
| `Redis` | ✅ | `backend_net` | intern | intern-only Cache | optional named volume statt anonym |
|
||||
| `mealie-postgres` | ⏳ | `mealie_internal` | intern | nur intern, nie `frontend_net` | aus `frontend_net` raus; Secret-Datei |
|
||||
| `immich_postgres` | ⏳ | `immich_default` | intern | intern-only | Passwort rotieren; named volume prüfen |
|
||||
| `immich_redis` | ⏳ | `immich_default` | intern | intern-only | anonymes Volume perspektivisch bereinigen |
|
||||
| `scanopy-postgres` | ⏳ | `scanopy_scanopy` | intern | intern-only | Passwort rotieren (aktuell Wiederverwendung) |
|
||||
|
||||
### 7.4 Öffentliche Apps
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `paperless-ngx` | ⏳ | `frontend_net`, `backend_net` | Traefik | vorbereitete Labels final aktivieren | `traefik.enable=true`; echte Domain; Port entfernen; Secret-Datei |
|
||||
| `Paperless-AI` | ⏳ | `frontend_net` | Traefik oder intern | Port nicht mehr direkt offen | echte Domain; Labels aktivieren |
|
||||
| `mealie` | ⏳ | `frontend_net`, `mealie_internal` | Traefik | sauber getrennte App/DB-Struktur | Port entfernen; Secret-Datei |
|
||||
| `gotify` | ⏳ | `frontend_net` | Traefik oder intern | intern per Container-Name für `diun` erreichbar | Passwort rotieren; Port entfernen |
|
||||
| `gitea` | ⏳ | `frontend_net` | Traefik + SSH | Web via Traefik, SSH-Port bleibt | HTTP-Labels sauberziehen |
|
||||
| `immich_server` | ⏳ | `immich_default`, `frontend_net` | Traefik | internes Immich-Netz bleibt; Web via Traefik | Port 2283 entfernen; Secret-Datei; `frontend_net` ergänzen |
|
||||
| `immich_machine_learning` | ✅ | `immich_default` | intern | bleibt intern | — |
|
||||
| `Stash` | ⏳ | `frontend_net` | intern oder Traefik | aus `bridge` raus; nur veröffentlichen wenn bewusst gewünscht | Port entfernen; ggf. Traefik-Labels |
|
||||
|
||||
### 7.5 Admin / Operations
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `code-server` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | nicht öffentlich offen | `PASSWORD` → `HASHED_PASSWORD`; Secret-Datei |
|
||||
| `PortainerCE` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | keine Host-Ports | echte Domain; Labels aktivieren; direkte Ports entfernen; **Docker-Socket nicht blind auf `:ro`** |
|
||||
| `Dozzle` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | keine Host-Ports | Labels aktivieren; direkte Ports entfernen |
|
||||
| `filebrowser` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | aus `bridge`; breite FS-Mounts prüfen | Port entfernen; Mounts einschränken |
|
||||
| `scanopy-server` | ⏳ | `scanopy_scanopy`, `frontend_net` | Traefik + Middleware / Tailscale-only | kein direkter Host-Port | `frontend_net` ergänzen; Port entfernen |
|
||||
| `luckyBackup` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | aus `bridge`; nur intern | Port entfernen; breite Mounts prüfen |
|
||||
|
||||
### 7.6 Monitoring / Status
|
||||
|
||||
| Container | Status | Soll-Netz(e) | Finaler Zugang | Finaler Sollzustand | Offene Punkte |
|
||||
|---|---|---|---|---|---|
|
||||
| `UptimeKuma` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | keine direkten Ports | Labels sauberziehen; Port entfernen |
|
||||
| `dashdot` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | keine direkten Ports | Placeholder-Domain raus; Labels aktivieren |
|
||||
| `Glances` | ⏳ | `host` | Tailscale-only | Host-Metriken | optional später hinter Traefik, aber nicht nötig |
|
||||
| `netdata` | ⏳ | `host` | Tailscale-only | Host-Metriken | `restart` fixen; leere CLAIM-Vars aufräumen |
|
||||
| `scrutiny` | ⏳ | `frontend_net` | Traefik + Middleware / Tailscale-only | aus `bridge`; echtes Image beibehalten | Ports entfernen; später prüfen, ob `privileged` reduziert werden kann |
|
||||
| `netalertx` | ✅ | `host` | Tailscale-only | Host-/Netzsicht bleibt | optional später hinter Traefik, aber kein Muss |
|
||||
|
||||
---
|
||||
|
||||
## 8. Traefik-Label-Standard
|
||||
|
||||
Jeder Dienst mit Traefik-Routing nutzt dieses Muster:
|
||||
|
||||
```yaml
|
||||
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 für Admin-Dienste
|
||||
```yaml
|
||||
- traefik.http.routers.<name>.middlewares=dashboard-auth@file,secure-headers@file
|
||||
```
|
||||
|
||||
### Regeln
|
||||
- `traefik.docker.network` immer explizit auf `frontend_net`
|
||||
- keine `yourdomain.tld`-Platzhalter
|
||||
- certresolver immer `le`
|
||||
- wenn Traefik aktiv ist, werden direkte Host-Ports entfernt
|
||||
- Admin-Dienste niemals ohne Middleware veröffentlichen
|
||||
|
||||
---
|
||||
|
||||
## 9. Migrationsstrategie (Blöcke A–F)
|
||||
|
||||
**Letzte Aktualisierung:** 2026-03-23
|
||||
|
||||
### Block A — Quick Wins (geringes Risiko, sofort)
|
||||
|
||||
```text
|
||||
[ ] restart: unless-stopped für:
|
||||
- Tailscale-Docker
|
||||
- binhex-official-pihole
|
||||
- postgresql17
|
||||
- vaultwarden
|
||||
- mail-archiver
|
||||
- scrutiny
|
||||
- netdata
|
||||
- Stash
|
||||
- Plex-Media-Server
|
||||
|
||||
[ ] vaultwarden ADMIN_TOKEN-Doppelpräfix korrigieren
|
||||
[ ] backrest DNS-Hardcoding entfernen
|
||||
[ ] diun ↔ gotify Erreichbarkeit prüfen / herstellen
|
||||
[ ] leere Netzwerke prüfen und entfernen: br0, immich_net, kopia_default, netbox_default
|
||||
[ ] ungenutzte anonyme Volumes prüfen
|
||||
```
|
||||
|
||||
### Block B — Kritische Kernmigrationen (höchste Priorität)
|
||||
|
||||
```text
|
||||
[ ] vaultwarden
|
||||
- von bridge weg
|
||||
- Host-Port weg
|
||||
- Secret-Datei
|
||||
- Traefik sauber aktiv
|
||||
|
||||
[ ] postgresql17
|
||||
- Port 5432 entfernen
|
||||
- nur backend_net
|
||||
- Secret-Datei
|
||||
- aus bridge raus
|
||||
|
||||
[ ] diun
|
||||
- Join zu frontend_net
|
||||
- gotify via Container-Name
|
||||
|
||||
[ ] mealie-postgres
|
||||
- aus frontend_net raus
|
||||
- mealie_internal
|
||||
```
|
||||
|
||||
### Block C — Frontend-Stack finalisieren
|
||||
|
||||
```text
|
||||
[ ] paperless-ngx
|
||||
- traefik.enable=true
|
||||
- paperless.kaleschke.info
|
||||
- Port entfernen
|
||||
|
||||
[ ] Paperless-AI
|
||||
- traefik.enable=true
|
||||
- paperless-ai.kaleschke.info
|
||||
- Port entfernen
|
||||
|
||||
[ ] PortainerCE
|
||||
- traefik.enable=true
|
||||
- portainer.kaleschke.info
|
||||
- Middleware
|
||||
- direkte Ports entfernen
|
||||
|
||||
[ ] Dozzle
|
||||
- traefik.enable=true
|
||||
- dozzle.kaleschke.info
|
||||
- Middleware
|
||||
- direkte Ports entfernen
|
||||
|
||||
[ ] dashdot
|
||||
- traefik.enable=true
|
||||
- dash.kaleschke.info
|
||||
- Middleware
|
||||
- direkte Ports entfernen
|
||||
|
||||
[ ] theme-park
|
||||
- nur wenn wirklich benötigt veröffentlichen
|
||||
```
|
||||
|
||||
### Block D — Bridge-/Dockerman-Container in Compose
|
||||
|
||||
```text
|
||||
[ ] vaultwarden
|
||||
[ ] postgresql17
|
||||
[ ] mail-archiver
|
||||
[ ] scrutiny
|
||||
[ ] filebrowser
|
||||
[ ] luckyBackup
|
||||
[ ] Stash
|
||||
[ ] Tailscale-Docker
|
||||
[ ] netdata
|
||||
[ ] Plex-Media-Server
|
||||
[ ] binhex-official-pihole
|
||||
```
|
||||
|
||||
### Block E — Secrets-Migration
|
||||
|
||||
```text
|
||||
[ ] vaultwarden → ADMIN_TOKEN_FILE
|
||||
[ ] postgresql17 → POSTGRES_PASSWORD_FILE
|
||||
[ ] mail-archiver → Authentication__Password_FILE
|
||||
[ ] mealie → POSTGRES_PASSWORD_FILE
|
||||
[ ] mealie-postgres → POSTGRES_PASSWORD_FILE
|
||||
[ ] gotify → Passwort rotieren + Secret-Datei
|
||||
[ ] diun → GOTIFY token als Datei
|
||||
[ ] paperless-ngx → PAPERLESS_DBPASS_FILE
|
||||
[ ] code-server → HASHED_PASSWORD / Secret
|
||||
[ ] immich_server → DB_PASSWORD rotieren + Datei
|
||||
[ ] immich_postgres → POSTGRES_PASSWORD_FILE
|
||||
[ ] scanopy-postgres → Passwort rotieren
|
||||
```
|
||||
|
||||
### Block F — Feinschliff / Hardening
|
||||
|
||||
```text
|
||||
[ ] backrest
|
||||
- traefik.docker.network → frontend_net
|
||||
- Mounts straffen
|
||||
|
||||
[ ] Redis
|
||||
- optional named volume
|
||||
|
||||
[ ] immich_redis
|
||||
- optional named volume
|
||||
|
||||
[ ] netdata
|
||||
- leere CLAIM-Vars entfernen
|
||||
|
||||
[ ] scrutiny
|
||||
- später prüfen, ob privileged reduziert werden kann
|
||||
|
||||
[ ] Tailscale-Docker
|
||||
- später prüfen, ob TS_USERSPACE/privileged bereinigt werden kann
|
||||
|
||||
[ ] Pi-hole
|
||||
- zuletzt konsolidieren, nicht als Erstprojekt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Bekannte Ausnahmen und Begründungen
|
||||
|
||||
| Container | Ausnahme | Begründung |
|
||||
|---|---|---|
|
||||
| `traefik` | Host-Ports 80/443 | zentraler Reverse Proxy |
|
||||
| `Tailscale-Docker` | `host`, aktuell `privileged`, `TS_USERSPACE=true` | bestehender VPN-Zugang; Umstellung nur kontrolliert |
|
||||
| `binhex-official-pihole` | `host` | DNS-/DHCP-naher Sonderfall |
|
||||
| `Plex-Media-Server` | `host` | Discovery / mDNS / Plex GDM |
|
||||
| `netdata` | `host` + zusätzliche Rechte | Host-Metriken |
|
||||
| `Glances` | `host` | Host-Metriken |
|
||||
| `netalertx` | `host` + Netzwerksicht | ARP / Netzwerkscan |
|
||||
| `scanopy-daemon` | `host`, aktuell privilegiert | hardware-/systemnaher Sonderfall |
|
||||
| `PortainerCE` | Docker-Socket nicht dogmatisch `:ro` | Management-UI; Schreiboperationen können nötig sein |
|
||||
|
||||
---
|
||||
|
||||
## 11. Projektorganisation und Arbeitsmodus
|
||||
|
||||
### 11.1 Unser Arbeitsprinzip
|
||||
Dieses Projekt wird **blockweise** umgesetzt, nicht wild containerweise.
|
||||
|
||||
### 11.2 Reihenfolge der Umsetzung
|
||||
1. **Sprint 1:** Quick Wins + `vaultwarden`
|
||||
2. **Sprint 2:** `postgresql17` + `diun/gotify`
|
||||
3. **Sprint 3:** `mealie` / `mealie-postgres` + `mail-archiver`
|
||||
4. **Sprint 4:** Frontend-Stack (`paperless`, `Portainer`, `Dozzle`, `dashdot`, etc.)
|
||||
5. **Sprint 5:** Compose-Migration der Dockerman-Container
|
||||
6. **Sprint 6:** Hardening / Secrets / Volumes / Sonderfälle
|
||||
|
||||
### 11.3 Regel für jede Änderung
|
||||
Jeder Sprint folgt demselben Schema:
|
||||
|
||||
1. Zielbild in diesem Dokument prüfen
|
||||
2. nur den aktuellen Block anfassen
|
||||
3. Compose-Datei ändern
|
||||
4. deployen
|
||||
5. testen
|
||||
6. dokumentieren / abhaken
|
||||
7. erst dann nächster Schritt
|
||||
|
||||
### 11.4 Source-of-Truth-Hierarchie
|
||||
1. **Dieses Dokument**
|
||||
2. Compose-Dateien
|
||||
3. operative Checklisten / Excel
|
||||
4. ad-hoc Notizen / Chat
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
---
|
||||
|
||||
## 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 alle Web-UIs, `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, keine produktiven `bridge`-Container mehr.
|
||||
Reference in New Issue
Block a user