# Traefik Stack - Reverse Proxy with SSL ## Overview Traefik acts as the central reverse proxy for all services, handling: - Automatic SSL certificate generation via Let's Encrypt - HTTP to HTTPS redirection - Service discovery via Docker labels - Security headers and compression - Rate limiting and access control ## Services - **traefik.michaelschiemer.de** - Traefik Dashboard (BasicAuth protected) ## Prerequisites 1. **Docker Network** ```bash docker network create traefik-public ``` 2. **ACME Storage File** ```bash touch acme.json chmod 600 acme.json ``` 3. **DNS Configuration** Point these domains to your server IP (94.16.110.151): - `michaelschiemer.de` - `*.michaelschiemer.de` (wildcard) ## Configuration ### 1. Create Environment File ```bash cp .env.example .env ``` ### 2. Generate Dashboard Password ```bash # Generate password hash htpasswd -nb admin your_secure_password # Example output: # admin:$apr1$8kj9d7lj$r.x5jhLVPLuCDLvJ6x0Hd0 # Important: In docker-compose.yml, replace $ with $$ # admin:$$apr1$$8kj9d7lj$$r.x5jhLVPLuCDLvJ6x0Hd0 ``` Update the `traefik.http.middlewares.traefik-auth.basicauth.users` label in `docker-compose.yml`. ### 3. Adjust Configuration (Optional) Edit `traefik.yml` for: - Log levels - Certificate resolvers - Additional entry points - Metrics configuration ## Deployment ### Initial Setup ```bash # Create network docker network create traefik-public # Create acme.json touch acme.json chmod 600 acme.json # Create log directories mkdir -p logs # Start Traefik docker compose up -d ``` ### Verify Deployment ```bash # Check container status docker compose ps # Check logs docker compose logs -f # Test dashboard access curl -I https://traefik.michaelschiemer.de # Check certificate openssl s_client -connect traefik.michaelschiemer.de:443 -servername traefik.michaelschiemer.de < /dev/null ``` ## Middleware Configuration Traefik provides several reusable middlewares in `dynamic/middlewares.yml`: ### Security Headers ```yaml labels: - "traefik.http.routers.myapp.middlewares=security-headers-global@file" ``` ### Rate Limiting ```yaml labels: # Strict: 50 req/s - "traefik.http.routers.myapp.middlewares=rate-limit-strict@file" # Moderate: 100 req/s - "traefik.http.routers.myapp.middlewares=rate-limit-moderate@file" # Lenient: 200 req/s - "traefik.http.routers.myapp.middlewares=rate-limit-lenient@file" ``` ### Compression ```yaml labels: - "traefik.http.routers.myapp.middlewares=gzip-compression@file" ``` ### Middleware Chains ```yaml labels: # Default chain: Security + Compression - "traefik.http.routers.myapp.middlewares=default-chain@file" # Admin chain: Security + Compression + Rate Limiting - "traefik.http.routers.myapp.middlewares=admin-chain@file" ``` ## Service Integration ### Example Service Configuration Add these labels to any Docker service to expose it through Traefik: ```yaml services: myapp: image: myapp:latest networks: - traefik-public labels: # Enable Traefik - "traefik.enable=true" # Router configuration - "traefik.http.routers.myapp.rule=Host(`app.michaelschiemer.de`)" - "traefik.http.routers.myapp.entrypoints=websecure" - "traefik.http.routers.myapp.tls=true" - "traefik.http.routers.myapp.tls.certresolver=letsencrypt" # Service configuration - "traefik.http.services.myapp.loadbalancer.server.port=80" # Middleware (optional) - "traefik.http.routers.myapp.middlewares=default-chain@file" networks: traefik-public: external: true ``` ## Monitoring ### Dashboard Access Access the Traefik dashboard at: https://traefik.michaelschiemer.de Default credentials (change in production): - Username: `admin` - Password: (set via htpasswd) ### Logs ```bash # Access logs (HTTP requests) tail -f logs/access.log # Traefik logs (errors, warnings) tail -f logs/traefik.log # Container logs docker compose logs -f traefik ``` ### Prometheus Metrics Traefik exposes Prometheus metrics for monitoring: ```yaml # Add to Prometheus scrape config - job_name: 'traefik' static_configs: - targets: ['traefik:8082'] ``` ## Troubleshooting ### Certificate Issues ```bash # Check acme.json permissions ls -la acme.json # Should be: -rw------- (600) # View certificate status docker compose logs traefik | grep -i "certificate" # Force certificate renewal rm acme.json touch acme.json chmod 600 acme.json docker compose restart ``` ### DNS Issues ```bash # Verify DNS resolution dig michaelschiemer.de dig git.michaelschiemer.de # Check from external nslookup michaelschiemer.de 8.8.8.8 ``` ### Service Not Accessible ```bash # Check Traefik can reach service docker network inspect traefik-public # Verify service labels docker inspect | grep -A 20 Labels # Check Traefik logs for routing errors docker compose logs traefik | grep -i error ``` ### Port Conflicts ```bash # Check if ports 80/443 are free sudo netstat -tlnp | grep -E ':80|:443' # Stop conflicting services sudo systemctl stop nginx # or apache2 ``` ## Security Hardening ### 1. IP Whitelisting Uncomment and configure in `dynamic/middlewares.yml`: ```yaml admin-whitelist: ipWhiteList: sourceRange: - "your.vpn.ip.range/32" - "10.0.0.0/8" ``` ### 2. Strong Dashboard Password ```bash # Generate strong password openssl rand -base64 32 # Create hash htpasswd -nb admin "your_strong_password" ``` ### 3. Rate Limiting Apply rate limiting to sensitive endpoints: ```yaml labels: - "traefik.http.routers.admin.middlewares=rate-limit-strict@file" ``` ### 4. DDoS Protection ```yaml # In traefik.yml - add entry point middleware entryPoints: websecure: address: ":443" http: middlewares: - rate-limit-moderate@file ``` ## Backup ### Important Files - `acme.json` - SSL certificates - `traefik.yml` - Static configuration - `dynamic/` - Dynamic configuration ```bash # Backup certificates cp acme.json acme.json.backup.$(date +%Y%m%d) # Backup configuration tar -czf traefik-config-backup.tar.gz traefik.yml dynamic/ ``` ## Updates ```bash # Pull latest image docker compose pull # Restart with new image docker compose up -d # Verify docker compose ps docker compose logs -f ``` ## Performance Tuning ### Connection Limits In `traefik.yml`: ```yaml entryPoints: websecure: transport: respondingTimeouts: readTimeout: 60s writeTimeout: 60s lifeCycle: requestAcceptGraceTimeout: 0s graceTimeOut: 10s ``` ### Resource Limits In `docker-compose.yml`: ```yaml deploy: resources: limits: memory: 512M cpus: '0.5' reservations: memory: 256M cpus: '0.25' ``` ## Support For issues with Traefik configuration: 1. Check official Traefik documentation: https://doc.traefik.io/traefik/ 2. Review logs: `docker compose logs -f` 3. Verify network connectivity: `docker network inspect traefik-public`