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

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.