# ============================================================================= # 03_stack-frontend.yml – Phase 4 # Web-App-Stack: alle Container mit Web-UI # ============================================================================= # # FIXES in dieser Version: # - Portainer: Port-Mapping korrigiert (9000:9000 + 9443:9443) # - paperless-ngx: Redis-URL mit Auth (redis://:PASS@Redis:6379) # - paperless-ngx: dual-homed frontend_net + backend_net # - Vaultwarden: TLS-Situation dokumentiert und geklärt (siehe unten) # - Kritische Images gepinnt (redis, portainer, pihole, paperless) # # TRAEFIK: noch nicht vorhanden # → Host-Ports bleiben als bewusste Übergangslösung offen # → traefik.enable=false überall — Labels sind vorbereitet, aber inaktiv # → Aktivierung: siehe 04_stack-traefik.yml und MIGRATION.md Phase 5 # # STARTREIHENFOLGE (depends_on greift nicht über Stack-Grenzen!): # 1. 01_stack-backend.yml hochfahren und Health abwarten # 2. Erst dann paperless-ngx starten # 3. Alle anderen können parallel starten # Nicht blind: docker compose -f 03_stack-frontend.yml up -d # Besser: Wellen laut MIGRATION.md Phase 4 # # ============================================================================= networks: frontend_net: external: true backend_net: external: true services: # --------------------------------------------------------------------------- # PORTAINER CE # FIX: Port-Mapping war falsch verdreht. # Korrekt: 9000=HTTP-UI, 9443=HTTPS-UI # --------------------------------------------------------------------------- PortainerCE: image: portainer/portainer-ce:2.21.5 # gepinnt container_name: PortainerCE restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/portainer:/data - /var/run/docker.sock:/var/run/docker.sock:rw networks: frontend_net: ipv4_address: 172.30.0.10 ports: - "9000:9000" # HTTP-UI - "9443:9443" # HTTPS-UI labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/EMP83/unraid-templates/main/PortainerCE/Portainer.png" net.unraid.docker.webui: "http://[IP]:[PORT:9000]/" traefik.enable: "false" traefik.http.routers.portainer.rule: "Host(`portainer.yourdomain.tld`)" traefik.http.routers.portainer.entrypoints: "websecure" traefik.http.routers.portainer.tls.certresolver: "letsencrypt" traefik.http.services.portainer.loadbalancer.server.port: "9000" traefik.docker.network: "frontend_net" # --------------------------------------------------------------------------- # PAPERLESS-NGX ← DUAL-HOMED # FIX 1: Redis-URL mit Passwort — ohne das crasht Paperless beim Start # FIX 2: in frontend_net UND backend_net gleichzeitig # # ACHTUNG: Nicht starten bevor 01_stack-backend.yml healthy ist! # postgresql17 und Redis müssen laufen, sonst schlägt der Start fehl. # restart:unless-stopped fängt das zwar ab, aber bewusst warten ist besser. # --------------------------------------------------------------------------- paperless-ngx: image: ghcr.io/paperless-ngx/paperless-ngx:2.20.10 # gepinnt container_name: paperless-ngx restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/documents/paperless:/usr/src/paperless/media - /mnt/user/documents/scans_inbox:/usr/src/paperless/consume - /mnt/user/appdata/paperless-ngx/data:/usr/src/paperless/data - /mnt/user/documents/paperless/export:/usr/src/paperless/export networks: frontend_net: ipv4_address: 172.30.0.17 # Traefik / Browser → paperless hier backend_net: ipv4_address: 172.21.0.20 # paperless → postgresql17 + Redis hier ports: - "8000:8000" # Übergang bis Traefik aktiv environment: PAPERLESS_DBENGINE: "postgresql" PAPERLESS_DBHOST: "postgresql17" PAPERLESS_DBPORT: "5432" PAPERLESS_DBNAME: "paperless" PAPERLESS_DBUSER: "paperless" PAPERLESS_DBPASS: "${PAPERLESS_DB_PASSWORD}" # FIX: Redis mit Auth — REDIS_PASSWORD kommt aus derselben .env wie Redis selbst PAPERLESS_REDIS: "redis://:${REDIS_PASSWORD}@Redis:6379" PAPERLESS_TIME_ZONE: "Europe/Berlin" PAPERLESS_OCR_LANGUAGE: "deu+eng" PAPERLESS_TIKA_ENABLED: "0" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/paperless.png" net.unraid.docker.webui: "http://[IP]:[PORT:8000]" traefik.enable: "false" traefik.http.routers.paperless.rule: "Host(`paperless.yourdomain.tld`)" traefik.http.routers.paperless.entrypoints: "websecure" traefik.http.routers.paperless.tls.certresolver: "letsencrypt" traefik.http.services.paperless.loadbalancer.server.port: "8000" traefik.docker.network: "frontend_net" # --------------------------------------------------------------------------- # VAULTWARDEN # # TLS-SITUATION (bitte einmal bewusst prüfen): # Aktuell: Port 4743 → HTTP (Port 80 intern) # Die gemounteten Zertifikate (cert.pem / key.pem) werden von Vaultwarden # nur genutzt, wenn ROCKET_TLS in den Env-Vars gesetzt ist. # Ohne diese Variable spricht Vaultwarden intern HTTP — die Zertifikate # haben dann keinen Effekt. # # Wahrscheinlichstes Szenario: Tailscale terminiert TLS davor → intern # läuft es HTTP → das ist bewusst so und vollkommen okay. # # Falls du HTTPS direkt in Vaultwarden willst, ergänze: # environment: # ROCKET_TLS: '{certs="/ssl/cert.pem",key="/ssl/key.pem"}' # # Für Phase 1: so lassen, Tailscale-Zugang funktioniert weiterhin. # --------------------------------------------------------------------------- vaultwarden: image: vaultwarden/server:1.35.4 # gepinnt container_name: vaultwarden restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/vaultwarden:/data - /mnt/user/appdata/vaultwarden/kallilabcore.taild9fcf2.ts.net.crt:/ssl/cert.pem:ro - /mnt/user/appdata/vaultwarden/kallilabcore.taild9fcf2.ts.net.key:/ssl/key.pem networks: frontend_net: ipv4_address: 172.30.0.16 ports: - "4743:80" # Tailscale terminiert TLS davor — bewusst so labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/vaultwarden.png" net.unraid.docker.webui: "https://kallilabcore.taild9fcf2.ts.net:4743/admin" traefik.enable: "false" traefik.http.routers.vault.rule: "Host(`vault.yourdomain.tld`)" traefik.http.routers.vault.entrypoints: "websecure" traefik.http.services.vault.loadbalancer.server.port: "80" traefik.docker.network: "frontend_net" # --------------------------------------------------------------------------- # PAPERLESS-AI # --------------------------------------------------------------------------- Paperless-AI: image: clusterzx/paperless-ai:latest container_name: Paperless-AI restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/paperless-ai:/app/data networks: frontend_net: ipv4_address: 172.30.0.18 ports: - "3236:3000" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/nwithan8/unraid_templates/master/images/paperless-ai-icon.png" net.unraid.docker.webui: "http://[IP]:[PORT:3000]/" traefik.enable: "false" traefik.http.routers.paperless-ai.rule: "Host(`paperless-ai.yourdomain.tld`)" traefik.http.routers.paperless-ai.entrypoints: "websecure" traefik.http.services.paperless-ai.loadbalancer.server.port: "3000" traefik.docker.network: "frontend_net" # --------------------------------------------------------------------------- # MAIL-ARCHIVER # Phase 1: konservativ — externe DB bleibt auf 192.168.178.58 # Separate Migration in Phase 3c (MIGRATION.md) # --------------------------------------------------------------------------- mail-archiver: image: s1t5/mailarchiver container_name: mail-archiver restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/mailarchiver/data-protection-keys:/app/DataProtection-Keys:rw networks: frontend_net: ipv4_address: 172.30.0.19 ports: - "5000:5000" environment: TZ: "Europe/Berlin" TimeZone__DisplayTimeZoneId: "Europe/Berlin" ConnectionStrings__DefaultConnection: "Host=192.168.178.58;Port=5432;Database=mailarchiver;Username=mailarchiver;Password=${MAILARCHIVER_DB_PASSWORD}" Authentication__Username: "${MAILARCHIVER_USERNAME}" Authentication__Password: "${MAILARCHIVER_PASSWORD}" Authentication__CookieName: "MailArchiverAuth" Authentication__SessionTimeoutMinutes: "60" OAuth__Enabled: "false" MailSync__IntervalMinutes: "15" MailSync__TimeoutMinutes: "60" MailSync__IgnoreSelfSignedCert: "false" MailSync__ConnectionTimeoutSeconds: "180" MailSync__CommandTimeoutSeconds: "300" BatchOperation__BatchSize: "50" BatchOperation__PauseBetweenEmailsMs: "50" BatchOperation__PauseBetweenBatchesMs: "250" BatchRestore__MaxAsyncEmails: "50000" BatchRestore__MaxSyncEmails: "150" BatchRestore__AsyncThreshold: "50" BatchRestore__DefaultBatchSize: "50" BatchRestore__SessionTimeoutMinutes: "30" Upload__MaxFileSizeGB: "10" Upload__RequestHeadersTimeoutHours: "2" Upload__KeepAliveTimeoutHours: "4" Selection__MaxSelectableEmails: "250" Npgsql__CommandTimeout: "900" HOST_OS: "Unraid" HOST_HOSTNAME: "Kallilabcore" HOST_CONTAINERNAME: "mail-archiver" ASPNETCORE_ENVIRONMENT: "Production" ASPNETCORE_URLS: "http://+:5000" logging: driver: json-file options: max-size: "50m" max-file: "1" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/rschuiling/unraid-templates/refs/heads/main/icons/envelope-check.png" net.unraid.docker.webui: "http://[IP]:[PORT:5000]" traefik.enable: "false" traefik.http.routers.mail.rule: "Host(`mail.yourdomain.tld`)" traefik.http.routers.mail.entrypoints: "websecure" traefik.http.services.mail.loadbalancer.server.port: "5000" traefik.docker.network: "frontend_net" # =========================================================================== # WELLE A – unkritisch, jederzeit migrierbar # =========================================================================== homarr: image: ghcr.io/homarr-labs/homarr:latest container_name: homarr restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - /mnt/user/appdata/homarr/appdata:/appdata networks: frontend_net: ipv4_address: 172.30.0.11 ports: - "10004:7575" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/manuel-rw/unraid-templates/master/templates/homarr/icon.png" net.unraid.docker.webui: "http://[IP]:[PORT:7575]/" traefik.enable: "false" traefik.http.routers.homarr.rule: "Host(`homarr.yourdomain.tld`)" traefik.http.routers.homarr.entrypoints: "websecure" traefik.http.services.homarr.loadbalancer.server.port: "7575" traefik.docker.network: "frontend_net" homepage: image: ghcr.io/gethomepage/homepage:latest container_name: homepage restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/homepage:/app/config - /mnt/user/appdata/homepage/config/public/images:/app/public/images - /var/run/docker.sock:/var/run/docker.sock:ro networks: frontend_net: ipv4_address: 172.30.0.12 ports: - "3000:3000" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/gethomepage/homepage/main/public/android-chrome-512x512.png" net.unraid.docker.webui: "http://[IP]:[PORT:3000]" traefik.enable: "false" traefik.http.routers.homepage.rule: "Host(`home.yourdomain.tld`)" traefik.http.routers.homepage.entrypoints: "websecure" traefik.http.services.homepage.loadbalancer.server.port: "3000" traefik.docker.network: "frontend_net" Dozzle: image: amir20/dozzle:v10.1.1 # gepinnt container_name: Dozzle restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/dozzle:/data - /var/run/docker.sock:/var/run/docker.sock:ro networks: frontend_net: ipv4_address: 172.30.0.13 ports: - "9888:8080" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/dozzle.png" net.unraid.docker.webui: "http://[IP]:[PORT:8080]/" traefik.enable: "false" traefik.http.routers.dozzle.rule: "Host(`dozzle.yourdomain.tld`)" traefik.http.routers.dozzle.entrypoints: "websecure" traefik.http.services.dozzle.loadbalancer.server.port: "8080" traefik.docker.network: "frontend_net" dashdot: image: mauricenino/dashdot:latest container_name: dashdot restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /etc/os-release:/etc/os-release:ro - /mnt:/mnt/host:ro networks: frontend_net: ipv4_address: 172.30.0.22 ports: - "3002:3001" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/manuel-rw/unraid-templates/master/templates/dashdot/dashdot.png" net.unraid.docker.webui: "http://[IP]:[PORT:3001]/" traefik.enable: "false" traefik.http.routers.dashdot.rule: "Host(`dash.yourdomain.tld`)" traefik.http.routers.dashdot.entrypoints: "websecure" traefik.http.services.dashdot.loadbalancer.server.port: "3001" traefik.docker.network: "frontend_net" theme-park: image: ghcr.io/themepark-dev/theme.park:1.22.0 # gepinnt container_name: theme-park restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/theme-park:/config networks: frontend_net: ipv4_address: 172.30.0.24 ports: - "8009:80" - "32770:443" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/themepark.png" net.unraid.docker.webui: "http://[IP]:[PORT:80]" traefik.enable: "false" traefik.http.routers.themepark.rule: "Host(`theme.yourdomain.tld`)" traefik.http.routers.themepark.entrypoints: "websecure" traefik.http.services.themepark.loadbalancer.server.port: "80" traefik.docker.network: "frontend_net" # =========================================================================== # WELLE B – mittelkritisch # =========================================================================== UptimeKuma: image: louislam/uptime-kuma:1 container_name: UptimeKuma restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/uptimekuma:/app/data - /var/run/docker.sock:/var/run/docker.sock:ro networks: frontend_net: ipv4_address: 172.30.0.14 ports: - "3001:3001" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/CorneliousJD/Docker-Templates/master/icons/uptimekuma.png" net.unraid.docker.webui: "http://[IP]:[PORT:3001]" traefik.enable: "false" traefik.http.routers.uptime.rule: "Host(`uptime.yourdomain.tld`)" traefik.http.routers.uptime.entrypoints: "websecure" traefik.http.services.uptime.loadbalancer.server.port: "3001" traefik.docker.network: "frontend_net" scrutiny: image: ghcr.io/starosdev/scrutiny:latest-omnibus container_name: scrutiny restart: unless-stopped cap_add: - SYS_RAWIO devices: - /dev/sdb:/dev/sdb - /dev/sdc:/dev/sdc - /dev/nvme0n1:/dev/nvme0n1 volumes: - /mnt/user/appdata/scrutiny/config:/opt/scrutiny/config - /mnt/user/appdata/scrutiny/influxdb:/opt/scrutiny/influxdb - /run/udev:/run/udev:ro networks: frontend_net: ipv4_address: 172.30.0.15 ports: - "8080:8080" - "8086:8086" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/Starosdev/scrutiny/master/webapp/frontend/src/assets/images/logo/scrutiny-logo-dark.png" net.unraid.docker.webui: "http://[IP]:[PORT:8080]/web/dashboard" traefik.enable: "false" traefik.http.routers.scrutiny.rule: "Host(`scrutiny.yourdomain.tld`)" traefik.http.routers.scrutiny.entrypoints: "websecure" traefik.http.services.scrutiny.loadbalancer.server.port: "8080" traefik.docker.network: "frontend_net" code-server: image: lscr.io/linuxserver/code-server:latest container_name: code-server restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/code-server:/config - /mnt/user:/mnt/user networks: frontend_net: ipv4_address: 172.30.0.20 ports: - "7258:8443" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/code-server-logo.png" net.unraid.docker.webui: "http://[IP]:[PORT:8443]" traefik.enable: "false" traefik.http.routers.code.rule: "Host(`code.yourdomain.tld`)" traefik.http.routers.code.entrypoints: "websecure" traefik.http.services.code.loadbalancer.server.port: "8443" traefik.docker.network: "frontend_net" # =========================================================================== # WELLE C – sensibel, einzeln migrieren # =========================================================================== luckyBackup: image: ghcr.io/ich777/luckybackup container_name: luckyBackup restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user:/mnt/user - /mnt/cache/appdata/luckybackup:/luckybackup networks: frontend_net: ipv4_address: 172.30.0.23 ports: - "7675:8080" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/ich777/docker-templates/master/ich777/images/luckybackup.png" net.unraid.docker.webui: "http://[IP]:[PORT:8080]/vnc.html?autoconnect=true" traefik.enable: "false" traefik.http.routers.backup.rule: "Host(`backup.yourdomain.tld`)" traefik.http.routers.backup.entrypoints: "websecure" traefik.http.services.backup.loadbalancer.server.port: "8080" traefik.docker.network: "frontend_net" Stash: image: stashapp/stash container_name: Stash restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /mnt/user/appdata/stash/blobs:/blobs - /mnt/user/appdata/stash/cache:/cache - /mnt/user/media/Heimatfilme:/data - /mnt/user/appdata/stash/generated:/generated - /mnt/user/appdata/stash/metadata:/metadata - /mnt/user/appdata/stash/config:/root/.stash networks: frontend_net: ipv4_address: 172.30.0.21 ports: - "6969:9999" labels: net.unraid.docker.managed: "dockerman" net.unraid.docker.icon: "https://raw.githubusercontent.com/CorneliousJD/Docker-Templates/master/icons/stash.png" net.unraid.docker.webui: "http://[IP]:[PORT:9999]" traefik.enable: "false" traefik.http.routers.stash.rule: "Host(`stash.yourdomain.tld`)" traefik.http.routers.stash.entrypoints: "websecure" traefik.http.services.stash.loadbalancer.server.port: "9999" traefik.docker.network: "frontend_net"