Traefik Reverse Proxy with Docker
Traefik is a modern reverse proxy and load balancer designed specifically for containerized environments, offering automatic servicio discovery, dynamic configuration, and Let's Cifra SSL/TLS support. Esta guía completa cubre Docker provider integration, routing configuration with labels, servicio discovery, SSL/TLS certificate management, middleware configuration, and advanced features. Traefik eliminates manual proxy configuration and scales seamlessly with your containerized infrastructure.
Tabla de Contenidos
- Comprendiendo Traefik
- Installing and Configuring Traefik
- Docker Provider Configuración
- Servicio Routing Configuración
- SSL/TLS with Let's Cifra
- Load Balancing Strategies
- Middleware Configuración
- Dashboard and Monitoreo
- Avanzado Features
- Conclusión
Comprendiendo Traefik
Traefik automatically discovers servicios in your Docker environment and configures reverse proxying without requiring manual configuration updates. It watches for Docker events and dynamically adjusts routing based on contenedor labels.
Key benefits:
- Automatic servicio discovery from Docker
- Dynamic configuration without restarts
- Built-in Let's Cifra support for SSL/TLS
- Web dashboard for monitoring and debugging
- Middleware for request/response modification
- Load balancing across contenedor instances
- API-driven configuration
- Multi-protocol support (HTTP, TCP, UDP)
Architecture components:
- Provider: Discovers servicios (Docker provider)
- Entrypoints: Red entry points (HTTP, HTTPS, etc.)
- Routers: Define routing rules and servicios
- Servicios: Backends receiving traffic
- Middleware: Transform requests/responses
Installing and Configuring Traefik
Despliega Traefik as a containerized servicio.
Basic Traefik setup:
# Crea Traefik configuration directory
mkdir -p /opt/traefik
cd /opt/traefik
# Crea traefik.yml configuration
cat > traefik.yml <<'EOF'
# API and dashboard
api:
insecure: false
dashboard: true
# Entrypoints
entryPoints:
http:
address: ":80"
https:
address: ":443"
# Docker provider
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
red: traefik
# Logging
log:
level: INFO
# Access logs
accessLog:
filePath: /logs/access.log
# Metrics
metrics:
prometheus: {}
EOF
# Crea docker-compose for Traefik
cat > docker-compose.yml <<'EOF'
version: '3.9'
servicios:
traefik:
imagen: traefik:v3.0
container_name: traefik
command:
- "--configFile=/traefik.yml"
puertos:
- "80:80"
- "443:443"
volúmenes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/traefik.yml
- ./acme.json:/acme.json
- ./logs:/logs
redes:
- traefik
restart: always
redes:
traefik:
driver: bridge
EOF
# Crea empty acme.json for Let's Cifra
touch acme.json
chmod 600 acme.json
mkdir -p logs
# Inicia Traefik
docker-compose up -d
# Verifica running
docker-compose ps
Traefik configuration with static config file:
cat > traefik-static.yml <<'EOF'
# Traefik Static Configuración
# API and Dashboard
api:
insecure: false
dashboard: true
debug: false
# Entrypoints
entryPoints:
http:
address: ":80"
http:
redirectEntryPoint: https
https:
address: ":443"
http:
tls:
certResolver: letsencrypt
# Providers
providers:
docker:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
red: traefik
file:
filename: /etc/traefik/dynamic.yml
watch: true
# Certificate resolution
certificateResolvers:
letsencrypt:
acme:
email: [email protected]
almacenamiento: /acme.json
httpChallenge:
entryPoint: http
# Logging
log:
level: INFO
filePath: /logs/traefik.log
# Access logs
accessLog:
filePath: /logs/access.log
format: json
# Metrics
metrics:
prometheus:
addEntryPointsLabels: true
addServicesLabels: true
EOF
# Use in contenedor
docker run -d \
--name traefik \
-p 80:80 \
-p 443:443 \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ./traefik-static.yml:/etc/traefik/traefik.yml \
-v ./acme.json:/acme.json \
-v ./logs:/logs \
traefik:v3.0
Docker Provider Configuración
Configura Traefik to automatically discover Docker servicios.
Docker provider configuration:
# In traefik.yml
cat >> traefik.yml <<'EOF'
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
red: "traefik"
swarmMode: false
useBindPortIP: false
EOF
# Reinicia Traefik
docker-compose restart traefik
# Verifica Docker provider connected
docker logs traefik | grep -i docker
Red configuration for servicio discovery:
# Docker Compose with Traefik red
cat > docker-compose.yml <<'EOF'
version: '3.9'
servicios:
traefik:
imagen: traefik:v3.0
redes:
- traefik
volúmenes:
- /var/run/docker.sock:/var/run/docker.sock
web:
imagen: nginx:alpine
redes:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(\`example.com\`)"
- "traefik.http.servicios.web.loadbalancer.server.puerto=80"
redes:
traefik:
driver: bridge
EOF
# Servicios must be on same red as Traefik for discovery
docker-compose up -d
Servicio Routing Configuración
Configura routing using Docker labels.
Basic routing with labels:
# Despliega servicio with routing labels
docker run -d \
--name myapp \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.myapp.rule=Host(\`app.example.com\`)" \
--label "traefik.http.routers.myapp.entrypoints=http,https" \
--label "traefik.http.servicios.myapp.loadbalancer.server.puerto=5000" \
myapp:latest
# Access via Traefik
curl http://app.example.com
Multiple routes for single servicio:
docker run -d \
--name api \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.api.rule=Host(\`api.example.com\`)" \
--label "traefik.http.routers.api-path.rule=Host(\`example.com\`) && PathPrefix(\`/api\`)" \
--label "traefik.http.servicios.api.loadbalancer.server.puerto=8080" \
myapi:latest
Path-based routing:
# Enruta by path prefix
docker run -d \
--name web \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.web.rule=PathPrefix(\`/\`)" \
--label "traefik.http.servicios.web.loadbalancer.server.puerto=80" \
nginx:latest
docker run -d \
--name app \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.app.rule=PathPrefix(\`/app\`)" \
--label "traefik.http.servicios.app.loadbalancer.server.puerto=5000" \
myapp:latest
# Traffic to /app/* goes to app servicio
# Other traffic goes to web servicio
Method-based routing:
# Enruta by HTTP method
docker run -d \
--name api \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.api-get.rule=Method(\`GET\`)" \
--label "traefik.http.routers.api-post.rule=Method(\`POST\`)" \
--label "traefik.http.servicios.api.loadbalancer.server.puerto=8080" \
api:latest
SSL/TLS with Let's Cifra
Configura automatic SSL/TLS certificate management.
Let's Cifra configuration:
cat > traefik.yml <<'EOF'
api:
insecure: false
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificateResolvers:
letsencrypt:
acme:
email: [email protected]
almacenamiento: /acme.json
httpChallenge:
entryPoint: http
log:
level: INFO
EOF
# Crea docker-compose with Let's Cifra
cat > docker-compose.yml <<'EOF'
version: '3.9'
servicios:
traefik:
imagen: traefik:v3.0
puertos:
- "80:80"
- "443:443"
- "8080:8080"
volúmenes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/traefik.yml
- ./acme.json:/acme.json
redes:
- traefik
restart: always
web:
imagen: nginx:alpine
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(\`example.com\`)"
- "traefik.http.routers.web.entrypoints=https"
- "traefik.http.routers.web.tls.certresolver=letsencrypt"
- "traefik.http.servicios.web.loadbalancer.server.puerto=80"
redes:
- traefik
redes:
traefik:
EOF
docker-compose up -d
DNS challenge for wildcard certificates:
# DNS challenge configuration (example with Cloudflare)
cat > traefik.yml <<'EOF'
certificateResolvers:
letsencrypt-dns:
acme:
email: [email protected]
almacenamiento: /acme.json
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 10
EOF
# Set DNS provider credentials
docker run -d \
--name traefik \
-e [email protected] \
-e CF_API_KEY=your-cloudflare-api-key \
-v ./traefik.yml:/traefik.yml \
traefik:v3.0
# Despliega servicio with wildcard cert
docker run -d \
--name api \
--label "traefik.enable=true" \
--label "traefik.http.routers.api.rule=Host(\`api.example.com\`) || Host(\`api.*.example.com\`)" \
--label "traefik.http.routers.api.entrypoints=https" \
--label "traefik.http.routers.api.tls.certresolver=letsencrypt-dns" \
--label "traefik.http.servicios.api.loadbalancer.server.puerto=8080" \
api:latest
Load Balancing Strategies
Implement different load balancing approaches.
Round-robin load balancing:
# Despliega multiple instances of same servicio
docker run -d \
--name app1 \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.app.rule=Host(\`app.example.com\`)" \
--label "traefik.http.servicios.app.loadbalancer.server.puerto=5000" \
--label "traefik.http.servicios.app.loadbalancer.passhostheader=true" \
app:latest
docker run -d \
--name app2 \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.app.rule=Host(\`app.example.com\`)" \
--label "traefik.http.servicios.app.loadbalancer.server.puerto=5000" \
app:latest
# Traefik automatically round-robins traffic
for i in {1..10}; do curl http://app.example.com; done
Weighted load balancing:
# Via docker-compose labels
version: '3.9'
servicios:
traefik:
imagen: traefik:v3.0
puertos:
- "80:80"
volúmenes:
- /var/run/docker.sock:/var/run/docker.sock
redes:
- traefik
app-prod:
imagen: app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(\`app.example.com\`)"
- "traefik.http.servicios.app.loadbalancer.server.puerto=5000"
- "traefik.http.servicios.app.loadbalancer.servers.0.url=http://app-prod:5000"
- "traefik.http.servicios.app.loadbalancer.servers.0.weight=3"
redes:
- traefik
app-canary:
imagen: app:beta
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(\`app.example.com\`)"
- "traefik.http.servicios.app.loadbalancer.servers.1.url=http://app-canary:5000"
- "traefik.http.servicios.app.loadbalancer.servers.1.weight=1"
redes:
- traefik
redes:
traefik:
# 75% traffic to prod, 25% to canary
Middleware Configuración
Apply middleware to modify requests and responses.
Adding request headers:
docker run -d \
--name app \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.app.rule=Host(\`app.example.com\`)" \
--label "traefik.http.routers.app.middlewares=add-headers" \
--label "traefik.http.middlewares.add-headers.headers.customrequestheaders.X-Custom-Header=CustomValue" \
--label "traefik.http.middlewares.add-headers.headers.customresponseheaders.X-Response-Header=ResponseValue" \
--label "traefik.http.servicios.app.loadbalancer.server.puerto=5000" \
app:latest
Rate limiting:
docker run -d \
--name api \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.api.rule=Host(\`api.example.com\`)" \
--label "traefik.http.routers.api.middlewares=ratelimit" \
--label "traefik.http.middlewares.ratelimit.ratelimit.average=10" \
--label "traefik.http.middlewares.ratelimit.ratelimit.burst=5" \
--label "traefik.http.servicios.api.loadbalancer.server.puerto=8080" \
api:latest
Authentication (Basic Auth):
# Generate htpasswd (username: admin, password: password)
htpasswd -c /tmp/.htpasswd admin
# Get base64 encoded value
cat /tmp/.htpasswd | base64
docker run -d \
--name secure-app \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.secure.rule=Host(\`secure.example.com\`)" \
--label "traefik.http.routers.secure.middlewares=basicauth" \
--label "traefik.http.middlewares.basicauth.basicauth.users=admin:passwordhash" \
--label "traefik.http.servicios.secure.loadbalancer.server.puerto=5000" \
app:latest
Dashboard and Monitoreo
Access Traefik's dashboard and monitoring features.
Habilita dashboard:
cat > traefik.yml <<'EOF'
api:
insecure: false
dashboard: true
entryPoints:
traefik:
address: ":8080"
EOF
# Protect dashboard with authentication
docker run -d \
--name traefik \
-p 80:80 \
-p 443:443 \
-p 8080:8080 \
--label "traefik.http.routers.dashboard.rule=Host(\`traefik.example.com\`)" \
--label "traefik.http.routers.dashboard.middlewares=basicauth" \
--label "traefik.http.middlewares.basicauth.basicauth.users=admin:hashedpassword" \
-v /var/run/docker.sock:/var/run/docker.sock \
traefik:v3.0
# Access dashboard
# http://traefik.example.com/dashboard/
Prometheus metrics:
cat > traefik.yml <<'EOF'
metrics:
prometheus:
addEntryPointsLabels: true
addServicesLabels: true
EOF
# Access metrics
curl http://localhost:8080/metrics
Avanzado Features
Implement advanced Traefik functionality.
TCP routing:
# Enruta TCP traffic (non-HTTP)
docker run -d \
--name tcp-app \
--red traefik \
--label "traefik.enable=true" \
--label "traefik.tcp.routers.mysql.rule=HostSNI(\`*\`)" \
--label "traefik.tcp.routers.mysql.entrypoints=mysql" \
--label "traefik.tcp.servicios.mysql.loadbalancer.server.puerto=3306" \
mysql:latest
# Configura TCP entrypoint
cat >> traefik.yml <<'EOF'
entryPoints:
mysql:
address: ":3306"
EOF
Servicio failover:
# Static file configuration for failover
cat > dynamic.yml <<'EOF'
http:
servicios:
api-failover:
loadBalancer:
healthChecks:
- uri: /health
interval: 10s
timeout: 5s
servers:
- url: http://api-primary:8080
- url: http://api-secondary:8080
EOF
# Traefik monitors health and fails over
Conclusión
Traefik proporciona a powerful, modern reverse proxy solution specifically designed for containerized environments. By leveraging Docker servicio discovery, automatic SSL/TLS management, and flexible middleware configuration, Traefik eliminates manual proxy configuration burden and scales seamlessly with your infrastructure. Whether deploying simple websites or complex microservices architectures, Traefik's label-based configuration and dynamic discovery capabilities provide elegant solutions. Inicia with basic routing and Let's Cifra configuration, progress to advanced middleware chains and load balancing strategies, and eventually integrate Traefik's dashboard for operational visibility. As your containerized infrastructure grows, Traefik becomes an indispensable component of your production deployment stack.


