Files
pangolin/.tasks/artifacts/traefik-analysis.md
Olaf b428721b07 Initial commit: cleaned project structure
- Consolidated documentation from Ralph Loop iterations
- Archived 20+ outdated/superseded files to .archive/
- Kept essential docs: OIDC integration, mobile setup, quick start
- Added operational scripts for health monitoring and backup
- Research artifacts preserved in .tasks/artifacts/

Current state:
- 3 VPS sites (fry, proton, photon) ONLINE in Pangolin
- brn-home site pending for local services (Jellyfin, etc.)
- Mobile access configuration pending

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 06:15:04 +00:00

349 lines
9.8 KiB
Markdown

# 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.<service-name>.rule=Host(`<domain>`)"
- "traefik.http.routers.<service-name>.entrypoints=websecure"
- "traefik.http.routers.<service-name>.tls=true"
- "traefik.http.routers.<service-name>.tls.certresolver=letsencrypt"
- "traefik.http.services.<service-name>.loadbalancer.server.port=<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:
<router-name>:
rule: "Host(`<domain>`)"
service: <service-name>
priority: 100
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
<service-name>:
loadBalancer:
servers:
- url: "http://<container-name>:<port>"
```
### 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://<container-name>:<port>`
2. **Host services:** `http://host.docker.internal:<port>`
---
## 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.<service>.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.