# Traefik Configuration Analysis **Analysis Date:** 2025-01-20 **Source:** /srv/docker/traefik/ **Purpose:** Document Traefik configuration for Authentik and Pangolin integration --- ## Docker Network Configuration ### Primary Network - **Network Name:** `traefik` - **Type:** External bridge network - **Subnet:** 172.19.0.0/16 - **Gateway:** 172.19.0.1 - **Network ID:** fffc2e33eb02203ed2ebd30725098d0ef8c7d5b0890fdf9a6d4aba5eb0784cc8 ### Connected Containers Currently attached services on the traefik network: - traefik (172.19.0.3) - transmission (172.19.0.2) - openwebui (172.19.0.4) - static-site-baumert-cc (172.19.0.5) - static-sites (172.19.0.6) - jellyfin (172.19.0.7) **CRITICAL:** All services that need Traefik routing must be connected to the `traefik` external network. --- ## Certificate Resolver Configuration ### ACME Settings - **Resolver Name:** `letsencrypt` - **Challenge Type:** DNS-01 (Exoscale) - **Provider:** exoscale - **DNS Resolvers:** 1.1.1.1:53, 8.8.8.8:53 - **Delay Before Check:** 30s - **ACME Email:** admin@obr.digital - **Storage Path:** /letsencrypt/acme.json ### Environment Variables Required ```bash EXOSCALE_API_KEY=EXO7929dee61aff39dce8dd104a EXOSCALE_API_SECRET=vgfgnK3fmB-76v-YrZSQuu6Q_gBY6OMsOP_QuWWcr1A ``` **Note:** DNS-01 challenge allows wildcard certificates and works without requiring ports 80/443 to be publicly accessible during certificate issuance. --- ## Traefik Label Patterns ### Standard Service Pattern (Docker Labels) Example from transmission service: ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.transmission.rule=Host(`transmission.local.obr.digital`)" - "traefik.http.routers.transmission.entrypoints=websecure" - "traefik.http.routers.transmission.tls=true" - "traefik.http.routers.transmission.tls.certresolver=letsencrypt" - "traefik.http.routers.transmission.service=transmission" - "traefik.http.services.transmission.loadbalancer.server.port=9091" ``` Example from openwebui service: ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.openwebui.rule=Host(`openwebui.local.obr.digital`)" - "traefik.http.routers.openwebui.entrypoints=websecure" - "traefik.http.routers.openwebui.tls=true" - "traefik.http.routers.openwebui.tls.certresolver=letsencrypt" - "traefik.http.services.openwebui.loadbalancer.server.port=8080" - "traefik.docker.network=traefik" ``` ### Label Pattern Template ```yaml labels: - "traefik.enable=true" - "traefik.http.routers..rule=Host(``)" - "traefik.http.routers..entrypoints=websecure" - "traefik.http.routers..tls=true" - "traefik.http.routers..tls.certresolver=letsencrypt" - "traefik.http.services..loadbalancer.server.port=" - "traefik.docker.network=traefik" # Required when service uses multiple networks ``` ### Middleware Pattern (Basic Auth) From Traefik dashboard configuration: ```yaml labels: - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$Di.EvXJZ$$z3Tc1Oss4W3nx/enE0gk71" - "traefik.http.routers.dashboard.middlewares=dashboard-auth" ``` **Note:** Dollar signs must be doubled (`$$`) in docker-compose files to escape them properly. --- ## Entry Points ### Configured Entry Points 1. **web** (Port 80) - Automatic redirect to HTTPS - Permanent redirect (301) - Scheme: https 2. **websecure** (Port 443) - TLS enabled by default - Primary entry point for all services 3. **metrics** (Port 8082) - Prometheus metrics endpoint - Internal only (not exposed in ports) ### Entry Point Configuration ```yaml command: - "--entrypoints.web.address=:80" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--entrypoints.web.http.redirections.entrypoint.permanent=true" - "--entrypoints.websecure.address=:443" - "--entrypoints.websecure.http.tls=true" ``` --- ## Dynamic Configuration Structure ### File Location - **Path:** /srv/docker/traefik/traefik_dynamic.yaml - **Mount:** Read-only volume in Traefik container - **Provider:** File provider enabled in Traefik config ### Dynamic Configuration Pattern The dynamic configuration file defines routers and services in YAML format: ```yaml http: routers: : rule: "Host(``)" service: priority: 100 entryPoints: - websecure tls: certResolver: letsencrypt services: : loadBalancer: servers: - url: "http://:" ``` ### Current Dynamic Routes The dynamic configuration currently handles: - Static sites (1.obr.sh, fw.obr.sh, brn.obnh.io) - Pi-hole admin (dns.obnh.io, dns.obnh.network) - routes to host.docker.internal:8080 - Transmission (tor.obnh.org, tor.obnh.network) - OpenWebUI (ll.obr.sh) - HTTPS fallback router (priority: 1) ### Service Backend Patterns 1. **Docker containers:** `http://:` 2. **Host services:** `http://host.docker.internal:` --- ## Traefik Provider Configuration ### Docker Provider ```yaml command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=traefik" ``` **Key Points:** - Services must explicitly set `traefik.enable=true` - Default network for label-based routing is `traefik` - Docker socket mounted read-only for security ### File Provider ```yaml command: - "--providers.file.filename=/traefik_dynamic.yaml" ``` --- ## API and Dashboard ### Dashboard Access - **URL:** https://traefik.local.obr.digital - **Authentication:** Basic Auth (admin:obr2024) - **Router:** dashboard - **Service:** api@internal - **TLS:** Let's Encrypt certificate ### API Configuration ```yaml command: - "--api.dashboard=true" - "--api.insecure=false" ``` --- ## Recommendations for Authentik Integration ### 1. Network Configuration Authentik services must be added to the `traefik` external network: ```yaml networks: - traefik - authentik-internal # For PostgreSQL/Redis internal communication ``` ### 2. Required Labels for Authentik Server ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.authentik.rule=Host(`auth.obr.digital`)" - "traefik.http.routers.authentik.entrypoints=websecure" - "traefik.http.routers.authentik.tls=true" - "traefik.http.routers.authentik.tls.certresolver=letsencrypt" - "traefik.http.services.authentik.loadbalancer.server.port=9000" - "traefik.docker.network=traefik" ``` ### 3. Forward Auth Middleware Pattern For protecting services with Authentik SSO: ```yaml labels: - "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik" - "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true" - "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid" - "traefik.http.routers..middlewares=authentik" ``` ### 4. Network Declaration in docker-compose.yml ```yaml networks: traefik: external: true authentik-internal: driver: bridge ``` --- ## Recommendations for Pangolin Integration ### 1. Service Labels ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.pangolin.rule=Host(`pangolin.obr.digital`)" - "traefik.http.routers.pangolin.entrypoints=websecure" - "traefik.http.routers.pangolin.tls=true" - "traefik.http.routers.pangolin.tls.certresolver=letsencrypt" - "traefik.http.services.pangolin.loadbalancer.server.port=8000" - "traefik.http.routers.pangolin.middlewares=authentik" - "traefik.docker.network=traefik" ``` ### 2. Network Configuration ```yaml networks: - traefik - pangolin-internal # For PostgreSQL internal communication ``` --- ## Security Considerations ### 1. Docker Socket Access - Traefik has read-only access to Docker socket - No containers can modify Docker state through Traefik ### 2. Exposed by Default - `exposedbydefault=false` requires explicit opt-in via labels - Prevents accidental service exposure ### 3. TLS Configuration - All services force HTTPS via websecure entry point - HTTP automatically redirects to HTTPS (permanent 301) - Let's Encrypt certificates auto-renewed ### 4. Metrics - Prometheus metrics on port 8082 - Not exposed externally in port mappings - Can be accessed internally by monitoring containers --- ## Files Reference ### Configuration Files 1. `/srv/docker/traefik/docker-compose.yml` - Main Traefik service definition 2. `/srv/docker/traefik/traefik_dynamic.yaml` - Dynamic file-based configuration 3. `/srv/docker/traefik/.env` - Exoscale API credentials 4. `/srv/docker/traefik/letsencrypt/acme.json` - Certificate storage (auto-generated) ### Example Service Configurations 1. `/srv/docker/transmission/docker-compose.yml` - Full label-based routing 2. `/srv/docker/openwebui/docker-compose.yml` - Multi-network service with Traefik 3. `/srv/docker/static-site/docker-compose.yml` - Minimal service (uses dynamic config) --- ## Summary for Integration Tasks ### For TASK-003 (Authentik Deployment) - Use external network: `traefik` - Certificate resolver: `letsencrypt` - Entry point: `websecure` - Suggested domain: `auth.obr.digital` - Required port: 9000 (Authentik server) - Add `traefik.docker.network=traefik` label (multi-network scenario) ### For TASK-008 (Pangolin Deployment) - Use external network: `traefik` - Certificate resolver: `letsencrypt` - Entry point: `websecure` - Suggested domain: `pangolin.obr.digital` - Required port: 8000 (typical Django/FastAPI port) - Apply Authentik forward auth middleware - Add `traefik.docker.network=traefik` label (multi-network scenario) ### Network Connectivity Both services must declare: ```yaml networks: traefik: external: true ``` This ensures they can communicate with Traefik and be discovered by its Docker provider.