Skip to main content
Back to Category

Traefik Reverse Proxy: Modern Load Balancer for Docker and Kubernetes

Traefik installation, automatic service discovery with Docker provider, Let's Encrypt SSL, middleware configuration, dashboard, Kubernetes Ingress Controller, and load balancing.

Read time: 18 min DevOps & Automation
traefikreverse proxyload balancerdockerkubernetesssldevops

Table of Contents

Traefik Reverse Proxy: Modern Load Balancer for Docker and Kubernetes

Traefik is a modern edge router and reverse proxy designed for microservice architectures. Thanks to its deep integration with Docker and Kubernetes, it automatically discovers and routes services.

What is Traefik?

Key features of Traefik:

  • Automatic service discovery: Automatic routing via Docker/Kubernetes labels
  • Let's Encrypt integration: Automatic SSL certificate management
  • Middleware system: Auth, rate limiting, redirect, headers
  • Dashboard: Real-time monitoring interface
  • Multiple providers: Docker, Kubernetes, Consul, etcd support
  • TCP/UDP routing: Support for non-HTTP protocols

Traefik v3 offers better performance and new features compared to v2. This guide focuses on Traefik v3.

Traefik v3 Installation

Installation with Docker Compose

hljs yaml
# docker-compose.yml
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard (close in production)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./config:/etc/traefik/config:ro
      - traefik_certs:/certs
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      # Dashboard
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hash"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"

volumes:
  traefik_certs:

networks:
  traefik-net:
    external: true

traefik.yml Configuration

hljs yaml
# traefik.yml
global:
  checkNewVersion: true
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false  # false in production

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true

  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt
    http3:
      advertisedPort: 443

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /certs/acme.json
      httpChallenge:
        entryPoint: web
      # DNS challenge (for wildcard)
      # dnsChallenge:
      #   provider: cloudflare
      #   resolvers:
      #     - "1.1.1.1:53"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-net
  file:
    directory: /etc/traefik/config
    watch: true

log:
  level: INFO
  filePath: /var/log/traefik/traefik.log

accessLog:
  filePath: /var/log/traefik/access.log
  bufferingSize: 100

Automatic Routing with Docker Provider

Register services automatically with Traefik using Docker labels:

hljs yaml
# Example application
services:
  webapp:
    image: nginx:alpine
    networks:
      - traefik-net
    labels:
      # Enable Traefik
      - "traefik.enable=true"

      # HTTP router
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"

      # Service port
      - "traefik.http.services.webapp.loadbalancer.server.port=80"

      # Apply middleware
      - "traefik.http.routers.webapp.middlewares=security-headers,rate-limit"

networks:
  traefik-net:
    external: true

Multi-Service Example

hljs yaml
services:
  api:
    image: myapi:latest
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      # Health check
      - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.api.loadbalancer.healthcheck.interval=30s"

  frontend:
    image: myfrontend:latest
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`example.com`) || Host(`www.example.com`)"
      - "traefik.http.routers.frontend.entrypoints=websecure"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

networks:
  traefik-net:
    external: true

Middleware Configuration

Static Middleware (traefik.yml or config file)

hljs yaml
# config/middlewares.yml
http:
  middlewares:
    # Security headers
    security-headers:
      headers:
        stsSeconds: 31536000
        stsIncludeSubdomains: true
        stsPreload: true
        forceSTSHeader: true
        contentTypeNosniff: true
        frameDeny: true
        referrerPolicy: "strict-origin-when-cross-origin"
        customResponseHeaders:
          X-Powered-By: ""
          Server: ""

    # Rate limiting
    rate-limit:
      rateLimit:
        average: 100
        burst: 50
        period: 1m
        sourceCriterion:
          ipStrategy:
            depth: 1

    # Basic auth
    basic-auth:
      basicAuth:
        users:
          - "admin:$apr1$xyz$hashedpassword"
        removeHeader: true

    # IP allowlist
    ip-whitelist:
      ipAllowList:
        sourceRange:
          - "192.168.1.0/24"
          - "10.0.0.0/8"

    # Redirect www to non-www
    www-redirect:
      redirectRegex:
        regex: "^https://www\\.(.*)"
        replacement: "https://${1}"
        permanent: true

    # Compress
    compress:
      compress:
        excludedContentTypes:
          - text/event-stream

Middleware via Labels

hljs yaml
labels:
  # Define and apply middleware
  - "traefik.http.middlewares.myapp-auth.basicauth.users=user:$$apr1$$hash"
  - "traefik.http.middlewares.myapp-ratelimit.ratelimit.average=50"
  - "traefik.http.middlewares.myapp-ratelimit.ratelimit.burst=20"
  - "traefik.http.routers.myapp.middlewares=myapp-auth,myapp-ratelimit"

  # Redirect middleware
  - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
  - "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"

Dashboard

hljs yaml
# Secure dashboard configuration
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
  - "traefik.http.routers.traefik-dashboard.service=api@internal"
  - "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
  - "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
  - "traefik.http.routers.traefik-dashboard.middlewares=dashboard-auth"
  - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$xyz$$hash"

Generating basic auth password:

hljs bash
# Generate password with htpasswd
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g

# Or with openssl
echo "admin:$(openssl passwd -apr1 'yourpassword')" | sed -e 's/\$/\$\$/g'

Kubernetes Ingress Controller

Installation with Helm

hljs bash
# Add Traefik Helm repository
helm repo add traefik https://traefik.github.io/charts
helm repo update

# Install Traefik
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --set deployment.replicas=2 \
  --set ports.web.redirectTo.port=websecure \
  --set ingressRoute.dashboard.enabled=true

IngressRoute (Traefik CRD)

hljs yaml
# ingressroute.yml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: webapp-ingress
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: webapp-service
          port: 80
      middlewares:
        - name: security-headers
  tls:
    certResolver: letsencrypt

Middleware CRD

hljs yaml
# middleware.yml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-headers
  namespace: default
spec:
  headers:
    stsSeconds: 31536000
    stsIncludeSubdomains: true
    contentTypeNosniff: true
    frameDeny: true

TCP/UDP Routing

hljs yaml
# traefik.yml - TCP entrypoint
entryPoints:
  mysql:
    address: ":3306"
  redis:
    address: ":6379"
hljs yaml
# config/tcp.yml
tcp:
  routers:
    mysql-router:
      entryPoints:
        - mysql
      rule: "HostSNI(`*`)"
      service: mysql-service

  services:
    mysql-service:
      loadBalancer:
        servers:
          - address: "mysql:3306"

Load Balancing

hljs yaml
# Load balancing with multiple instances
services:
  api:
    image: myapi:latest
    deploy:
      replicas: 3
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      # Sticky sessions
      - "traefik.http.services.api.loadbalancer.sticky.cookie=true"
      - "traefik.http.services.api.loadbalancer.sticky.cookie.name=traefik_session"
      - "traefik.http.services.api.loadbalancer.sticky.cookie.secure=true"
      # Health check
      - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
      - "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"

Conclusion

Traefik is a powerful reverse proxy and load balancer solution for modern microservice infrastructures. With its deep integration with Docker and Kubernetes, automatic SSL management, and rich middleware ecosystem, it's a reliable choice for production environments. Its label-based configuration allows each service to define its own routing rules.