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.
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
# 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
# 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:
# 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
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)
# 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
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
# 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:
# 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
# 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)
# 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
# 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
# traefik.yml - TCP entrypoint
entryPoints:
mysql:
address: ":3306"
redis:
address: ":6379"
# config/tcp.yml
tcp:
routers:
mysql-router:
entryPoints:
- mysql
rule: "HostSNI(`*`)"
service: mysql-service
services:
mysql-service:
loadBalancer:
servers:
- address: "mysql:3306"
Load Balancing
# 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.
Related Articles
Docker Compose Guide: Multi-Container Application Management
Define and manage multi-container applications with Docker Compose: service dependencies, environment variables, health checks, scaling, and production deployment. Comprehensive guide.
Automated Deployment with GitHub Actions: CI/CD Pipeline Setup
Build CI/CD pipelines with GitHub Actions: Docker build and push, SSH server deployment, test automation, secrets management, and workflow optimization.
Server Automation with Ansible: Infrastructure as Code
Ansible installation, inventory file, playbook writing, role structure, variables, encrypted vault, ad-hoc commands, and server configuration automation. Step-by-step guide.