--- title: Proxy - The Traffic Cop of Your Infrastructure description: "Beep beep! Make way for HTTPS traffic!" navigation: icon: i-lucide-traffic-cone --- > *"Beep beep! Make way for HTTPS traffic!"* - Traefik ## What's This All About? Traefik (pronounced "traffic") is your reverse proxy and load balancer extraordinaire! Think of it as the extremely organized doorman at a fancy hotel - it knows exactly where every guest (request) needs to go, handles their SSL certificates, redirects them when needed, and does it all with style! ## The Traffic Master ### :icon{name="lucide:target"} Traefik **Container**: `proxy_app` **Image**: `traefik:latest` **Ports**: 80 (HTTP), 443 (HTTPS), 8080 (Dashboard) **Home**: http://localhost:8080/dashboard/ Traefik is the Swiss Army knife of reverse proxies: - :icon{name="lucide:lock"} **Auto SSL**: Let's Encrypt certificates automatically - :icon{name="lucide:tag"} **Service Discovery**: Finds your containers via Docker labels - :icon{name="lucide:refresh-cw"} **Auto-Config**: No config files to edit (mostly!) - :icon{name="lucide:bar-chart"} **Dashboard**: Beautiful visual overview - :icon{name="lucide:zap"} **Fast**: Written in Go for max performance - :icon{name="lucide:plug"} **Middleware**: Compress, auth, rate limit, and more - :icon{name="lucide:target"} **Load Balancing**: Distribute traffic intelligently ## How It Works ``` Internet Request (https://yoursite.com) ↓ Traefik (Port 443) ├─ Checks Docker labels ├─ Finds matching service ├─ Terminates SSL ├─ Applies middleware └─ Forwards to container ↓ Your Service (blog, auth, etc.) ``` ## Configuration Breakdown ### Command Arguments Let's decode the Traefik startup commands: ```yaml --api.dashboard=true # Enable the fancy dashboard --api.insecure=true # Allow dashboard on :8080 (dev mode) --log.level=DEBUG # Verbose logging for troubleshooting --global.sendAnonymousUsage=false # No telemetry (privacy!) --global.checkNewVersion=true # Check for updates --providers.docker=true # Watch Docker for services --providers.docker.exposedbydefault=false # Require explicit labels --providers.docker.network=kompose # Use kompose network --entrypoints.web.address=:80 # HTTP on port 80 --entryPoints.web-secure.address=:443 # HTTPS on port 443 --certificatesresolvers.resolver.acme.tlschallenge=true # SSL verification --certificatesresolvers.resolver.acme.email=admin@example.com # For Let's Encrypt --certificatesresolvers.resolver.acme.storage=/letsencrypt/acme.json # Cert storage ``` ### Entry Points **web** (Port 80): - Receives HTTP traffic - Usually redirects to HTTPS **web-secure** (Port 443): - Handles HTTPS traffic - Terminates SSL here - Forwards decrypted traffic to services ### Certificate Resolver **Let's Encrypt Integration**: - Automatic SSL certificates - TLS challenge method - Stores certs in `/letsencrypt/acme.json` - Auto-renewal (60 days before expiry) ## Dashboard Access :icon{name="lucide:bar-chart"} ### Development/Testing ``` URL: http://localhost:8080/dashboard/ ``` **Features**: - :icon{name="lucide:clipboard"} All routers and services - :icon{name="lucide:lock"} Active certificates - :icon{name="lucide:globe"} Entry points status - :icon{name="lucide:bar-chart"} Real-time metrics - :icon{name="lucide:search"} Request logs ### Production (Secure It!) Add authentication to dashboard: ```yaml labels: - "traefik.http.routers.dashboard.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$password" ``` Generate password hash: ```bash htpasswd -nb admin your_password ``` ## Label-Based Configuration :icon{name="lucide:tag"} Every service in kompose uses Traefik labels. Here's what they mean: ### Basic Labels ```yaml labels: - 'traefik.enable=true' # "Hey Traefik, route me!" - 'traefik.http.routers.myapp-web.rule=Host(`app.example.com`)' # Domain routing - 'traefik.http.routers.myapp-web.entrypoints=web' # Use HTTP - 'traefik.http.services.myapp.loadbalancer.server.port=8080' # Internal port ``` ### HTTPS Setup ```yaml - 'traefik.http.routers.myapp-web-secure.rule=Host(`app.example.com`)' - 'traefik.http.routers.myapp-web-secure.entrypoints=web-secure' # HTTPS - 'traefik.http.routers.myapp-web-secure.tls.certresolver=resolver' # Auto SSL ``` ### HTTP → HTTPS Redirect ```yaml - 'traefik.http.middlewares.myapp-redirect.redirectscheme.scheme=https' - 'traefik.http.routers.myapp-web.middlewares=myapp-redirect' ``` ### Compression ```yaml - 'traefik.http.middlewares.myapp-compress.compress=true' - 'traefik.http.routers.myapp-web-secure.middlewares=myapp-compress' ``` ## Ports & Networking | Port | Purpose | Access | |------|---------|--------| | 80 | HTTP Traffic | Public | | 443 | HTTPS Traffic | Public | | 8080 | Dashboard | Local only (for now) | **Network**: `kompose` - must be created before starting: ```bash docker network create kompose ``` ## SSL Certificate Management :icon{name="lucide:lock"} ### Let's Encrypt Process 1. **Service starts** with Traefik labels 2. **Traefik detects** it needs SSL 3. **Requests certificate** from Let's Encrypt 4. **TLS challenge** runs (Traefik proves domain ownership) 5. **Certificate issued** (valid 90 days) 6. **Auto-renewal** happens at 60 days ### Certificate Storage ``` /var/local/data/traefik/letsencrypt/acme.json ``` **:icon{name="lucide:alert-triangle"} PROTECT THIS FILE!** - Contains private keys - Encrypted by Traefik - Backup regularly - Permissions: 600 ### View Certificates ```bash # In dashboard http://localhost:8080/dashboard/#/http/routers # Or check file sudo cat /var/local/data/traefik/letsencrypt/acme.json | jq '.resolver.Certificates' ``` ## Common Middleware :icon{name="lucide:wrench"} ### Rate Limiting ```yaml - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.ratelimit.ratelimit.burst=50" ``` ### IP Whitelist ```yaml - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=192.168.1.0/24" ``` ### CORS Headers ```yaml - "traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,POST,PUT" - "traefik.http.middlewares.cors.headers.accesscontrolalloworigin=*" ``` ### Basic Auth ```yaml - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$password" ``` ### Strip Prefix ```yaml - "traefik.http.middlewares.stripprefix.stripprefix.prefixes=/api" ``` ## Health Check :icon{name="lucide:hospital"} Traefik has a built-in health check: ```bash traefik healthcheck --ping ``` Runs every 30 seconds. If it fails 3 times, Docker restarts the container. ## Monitoring & Debugging ### Real-Time Logs ```bash docker logs proxy_app -f ``` ### Access Logs (Enable in config) ```yaml --accesslog=true --accesslog.filepath=/var/log/traefik/access.log ``` ### Metrics (Prometheus) ```yaml --metrics.prometheus=true --metrics.prometheus.buckets=0.1,0.3,1.2,5.0 ``` ## Adding a New Service 1. **Create compose file** with labels: ```yaml services: myapp: image: nginx networks: - kompose labels: - 'traefik.enable=true' - 'traefik.http.routers.myapp.rule=Host(`myapp.example.com`)' - 'traefik.http.routers.myapp.entrypoints=web-secure' - 'traefik.http.routers.myapp.tls.certresolver=resolver' ``` 2. **Start the service**: ```bash docker compose up -d ``` 3. **Traefik auto-detects** it! 4. **Check dashboard** to confirm routing ## Troubleshooting :icon{name="lucide:search"} **Q: Service not accessible?** ```bash # Check if Traefik sees it docker logs proxy_app | grep your-service # Verify labels docker inspect your-container | grep traefik ``` **Q: SSL certificate not working?** - Check domain DNS points to server - Verify port 80/443 are open - Check Let's Encrypt rate limits - Look for errors in logs **Q: "Gateway Timeout" errors?** - Service might be slow to respond - Check service health - Increase timeout in labels: ```yaml - "traefik.http.services.myapp.loadbalancer.healthcheck.timeout=10s" ``` **Q: HTTP not redirecting to HTTPS?** - Verify redirect middleware is applied - Check router configuration - Look for middleware typos **Q: Certificate renewal failing?** ```bash # Check renewal logs docker logs proxy_app | grep -i "renew\|certificate" # Ensure ports are accessible curl -I http://yourdomain.com/.well-known/acme-challenge/test ``` ## Advanced Configuration ### Multiple Domains ```yaml - 'traefik.http.routers.myapp.rule=Host(`app1.com`) || Host(`app2.com`)' ``` ### Path-Based Routing ```yaml - 'traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)' - 'traefik.http.routers.web.rule=Host(`example.com`) && PathPrefix(`/`)' ``` ### Weighted Load Balancing ```yaml services: app-v1: labels: - "traefik.http.services.myapp.loadbalancer.server.weight=90" app-v2: labels: - "traefik.http.services.myapp.loadbalancer.server.weight=10" ``` ## Security Best Practices :icon{name="lucide:shield"} 1. **Secure Dashboard**: - Add authentication - Or disable in production: `--api.dashboard=false` 2. **HTTPS Only**: - Always redirect HTTP → HTTPS - Use HSTS headers 3. **Regular Updates**: ```bash docker compose pull docker compose up -d ``` 4. **Backup Certificates**: ```bash cp /var/local/data/traefik/letsencrypt/acme.json ~/backups/ ``` 5. **Monitor Logs**: - Watch for unusual patterns - Set up alerts for errors ## Performance Tips :icon{name="lucide:zap"} 1. **Enable Compression**: Already done for most services! 2. **HTTP/2**: Automatically enabled with HTTPS 3. **Connection Pooling**: Traefik handles it 4. **Caching**: Use middleware or CDN 5. **Keep-Alive**: Enabled by default ## Fun Traefik Facts :icon{name="lucide:graduation-cap"} - Written in Go (blazing fast!) - Powers thousands of production systems - Open source since 2015 - Cloud-native from the ground up - Originally created for microservices - Supports Docker, Kubernetes, Consul, and more ## Resources - [Traefik Documentation](https://doc.traefik.io/traefik/) - [Let's Encrypt](https://letsencrypt.org/) - [Traefik Plugins](https://plugins.traefik.io/) --- *"Life is like a reverse proxy - it's all about routing requests to the right destination."* - Ancient Traefik Wisdom :icon{name="lucide:traffic-cone"}:icon{name="lucide:sparkles"}