Skip to main content

Traefik Configuration & Management

Comprehensive guide to Traefik v2.11 setup, configuration, and management.

Overview

Traefik is an advanced reverse proxy and load balancer that automatically discovers services and configures routing. It handles:
  • HTTP/HTTPS routing
  • SSL/TLS termination and certificate generation
  • Load balancing
  • Middleware application
  • Service discovery via Docker
Dashboard: https://traefik.starfleet-command.dev API: https://traefik.starfleet-command.dev/api/ Metrics Port: 8080 (insecure, internal only)

Configuration Files

Static Configuration (traefik.yml)

The static configuration file defines global settings that rarely change.
# API Dashboard
api:
  dashboard: true
  insecure: true  # Allows unsecured API access on port 8080

# Entry Points (listening ports)
entryPoints:
  web:                          # HTTP
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure         # Redirect HTTP to HTTPS
          scheme: https
  
  websecure:                    # HTTPS
    address: ":443"
    http:
      tls:
        certResolver: cloudflare

# Certificate Resolvers (ACME providers)
certificatesResolvers:
  cloudflare:
    acme:
      email: scott@rochecloud.dev
      storage: /acme/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

# Providers (service discovery)
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-proxy
  
  file:
    directory: /config
    watch: true

# Logging
log:
  level: INFO

accessLog: {}

Dynamic Configuration (Docker Labels)

Dynamic configuration is defined in docker-compose.yml using Docker labels. Example Service:
services:
  traefik:
    image: traefik:v2.11
    ports:
      - "80:80"
      - "443:443"
    environment:
      - CF_API_EMAIL=scott@rochecloud.dev
      - CF_DNS_API_TOKEN=your-token-here
    labels:
      # Enable routing for this service
      - "traefik.enable=true"
      
      # HTTPS Router
      - "traefik.http.routers.traefik.rule=Host(`traefik.starfleet-command.dev`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=cloudflare"
      
      # Service definition
      - "traefik.http.routers.traefik.service=api@internal"
      
      # Middleware
      - "traefik.http.routers.traefik.middlewares=descope-verify@docker"
      
      # HTTP to HTTPS redirect
      - "traefik.http.routers.traefik-http.rule=Host(`traefik.starfleet-command.dev`)"
      - "traefik.http.routers.traefik-http.entrypoints=web"
      - "traefik.http.routers.traefik-http.service=api@internal"
      - "traefik.http.middlewares.redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik-http.middlewares=redirect"

Routing Rules

Host-Based Routing

Route based on the requested hostname:
- "traefik.http.routers.myapp.rule=Host(`myapp.starfleet-command.dev`)"

Path-Based Routing

Route based on URL path:
- "traefik.http.routers.api.rule=Host(`api.starfleet-command.dev`) && Path(`/v1`)"

Combined Rules

# Route to service1 for api.domain.com/v1
- "traefik.http.routers.api-v1.rule=Host(`api.starfleet-command.dev`) && Path(`/v1`)"

# Route to service2 for api.domain.com/v2
- "traefik.http.routers.api-v2.rule=Host(`api.starfleet-command.dev`) && Path(`/v2`)"

Middleware

Middleware allows you to modify requests/responses and handle cross-cutting concerns.

Authentication Middleware

# Enable authentication for a route
- "traefik.http.routers.myapp.middlewares=descope-verify@docker"

# The middleware is defined in descope-auth service:
- "traefik.http.middlewares.descope-verify.forwardauth.address=http://descope-auth:3000/verify"
- "traefik.http.middlewares.descope-verify.forwardauth.authResponseHeaders=X-Forwarded-User"

Redirect Middleware

# Redirect HTTP to HTTPS
- "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"

Rate Limiting

# Limit to 100 requests per minute
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.ratelimit.ratelimit.period=1m"

Headers Modification

# Add custom headers
- "traefik.http.middlewares.headers.headers.customRequestHeaders.X-Custom-Header=value"
- "traefik.http.middlewares.headers.headers.customResponseHeaders.X-Custom-Response=value"

SSL/TLS Certificates

Automatic Certificate Generation

Traefik automatically generates certificates for routes with:
  • Entry point: websecure
  • TLS resolver: cloudflare
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=cloudflare"

ACME Challenge Flow

1. Traefik detects new route: myapp.starfleet-command.dev
2. Initiates Let's Encrypt ACME challenge
3. Uses Cloudflare DNS challenge
4. Updates DNS TXT record
5. Let's Encrypt verifies ownership
6. Certificate issued and stored in acme.json
7. Auto-renewal starts 30 days before expiration

Certificate Storage

Certificates stored in: /opt/traefik/acme/acme.json Never commit this file to Git - it contains private keys!

Load Balancing

Basic Load Balancing

If a service has multiple instances, Traefik automatically distributes traffic:
services:
  app1:
    image: myapp:latest
    networks:
      - traefik-proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.starfleet-command.dev`)"
      - "traefik.http.services.app.loadbalancer.server.port=8080"

  app2:
    image: myapp:latest
    networks:
      - traefik-proxy
    # Same labels - Traefik will load balance across both instances

Round-Robin Distribution

Traefik uses round-robin by default:
  1. Request 1 → app1
  2. Request 2 → app2
  3. Request 3 → app1
  4. Request 4 → app2

Health Checks

- "traefik.http.services.app.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.app.loadbalancer.healthcheck.interval=10s"

Service Discovery

Docker Provider

Traefik automatically discovers services with:
  • Enabled: traefik.enable=true
  • Network: traefik-proxy
  • Labels for configuration

Service Registration Process

1. Service starts with Docker
2. Traefik detects via Docker socket
3. Reads Docker labels
4. Creates router and service definitions
5. Applies middleware
6. Starts routing traffic

Monitoring & Troubleshooting

Dashboard Access

http://localhost:8080 (internal)
https://traefik.starfleet-command.dev (authenticated)
Dashboard shows:
  • Registered routers
  • Active services
  • Middleware definitions
  • Entry points
  • Health status

API Endpoints

GET /api/entrypoints      - List entry points
GET /api/routers          - List routers
GET /api/services         - List services
GET /api/middlewares      - List middleware
GET /api/providers        - List providers
GET /api/version          - Get Traefik version

Viewing Logs

# Follow Traefik logs
docker logs traefik -f

# Filter for errors
docker logs traefik | grep -i error

# Filter for ACME (certificates)
docker logs traefik | grep -i acme

Common Issues

Route Not Found (404)

Symptoms: Service returns 404 when accessed Causes:
  • Route not registered (check labels)
  • Service not on traefik-proxy network
  • Typo in hostname rule
Fix:
# Check registered routers
curl http://localhost:8080/api/http/routers

# Check service is on network
docker inspect service-name | grep traefik-proxy

# Check labels
docker inspect service-name | grep traefik

Certificate Not Generating

Symptoms: SSL certificate error, no HTTPS Causes:
  • DNS not resolving
  • Cloudflare API token invalid
  • Service not on websecure entrypoint
Fix:
# Check logs for ACME errors
docker logs traefik | grep -i acme

# Verify DNS
nslookup myapp.starfleet-command.dev

# Check Cloudflare token
echo $CF_DNS_API_TOKEN  # Verify it's set

Service Unreachable

Symptoms: 502 Bad Gateway Causes:
  • Backend service crashed
  • Wrong port configured
  • Service not on traefik-proxy network
Fix:
# Check service is running
docker ps | grep service-name

# Check logs
docker logs service-name

# Verify port
docker inspect service-name | grep -A 5 "ExposedPorts"

Best Practices

  1. Always use HTTPS
    • Redirect HTTP to HTTPS
    • Use websecure entrypoint
    • Configure certificate resolver
  2. Proper Naming
    • Use descriptive router names
    • Use lowercase with hyphens
    • Name services consistently
  3. Network Isolation
    • Always add services to traefik-proxy network
    • Use exposedByDefault: false in provider
    • Explicitly enable routing with labels
  4. Security
    • Use authentication middleware for sensitive services
    • Don’t expose sensitive endpoints
    • Keep credentials in environment variables
    • Rotate API tokens regularly
  5. Monitoring
    • Enable access logs
    • Monitor Traefik resource usage
    • Set up alerting for certificate expiration
    • Review logs for errors regularly
  6. Configuration Management
    • Keep docker-compose.yml in version control
    • Document custom middleware
    • Version your configuration changes
    • Test changes before deploying to production

Next: Descope Authentication Setup