Traefik
Reverse proxy specialized for cloud-native environments. Enables dynamic configuration management through Docker and Kubernetes integration. Automatic service discovery and load balancing capabilities.
Traefik Proxy
Traefik is a cloud-native reverse proxy and load balancer specialized for cloud-native environments. Through tight integration with Docker and Kubernetes, it automates dynamic service discovery and configuration management, providing an optimized design for microservices architectures.
Overview
Traefik is an HTTP reverse proxy and load balancer designed for microservices that automatically configures itself by integrating with existing infrastructure components. Unlike traditional reverse proxies that require manual configuration, Traefik uses service discovery to dynamically configure routing, eliminating the need for configuration updates and restarts when services are added, removed, or scaled.
Details
Traefik 2025 edition continues to establish itself as the leading cloud-native application proxy solution. With over 2 billion downloads and extensive adoption in production environments, Traefik has proven its reliability for managing complex distributed systems. The latest v3.4 series includes enhanced observability through expanded OpenTelemetry integration, improved security features, and advanced service discovery capabilities. Built in Go, Traefik provides high performance while maintaining simplicity in operation, making it capable of handling large, highly-complex deployments across public, private, and hybrid clouds.
Key Features
- Dynamic Service Discovery: Automatic detection and configuration of services
- Multi-Provider Support: Docker, Kubernetes, Consul, Etcd integration
- Let's Encrypt Integration: Automatic SSL certificate management
- Advanced Load Balancing: Multiple algorithms and health checking
- Comprehensive Observability: Metrics, tracing, and access logs
- Zero-Downtime Updates: Configuration changes without restarts
Pros and Cons
Pros
- Revolutionary dynamic service discovery eliminates manual configuration overhead
- Exceptional cloud-native integration with Kubernetes, Docker, and service meshes
- Zero-downtime configuration updates ensuring high availability during deployments
- Comprehensive observability features with OpenTelemetry, Prometheus, and Jaeger support
- Advanced load balancing capabilities including weighted routing and traffic mirroring
- Extensive middleware ecosystem for authentication, rate limiting, and security
- Production-proven scalability handling billions of requests across diverse environments
Cons
- Steeper learning curve compared to traditional reverse proxies for beginners
- Complex configuration scenarios may require deep understanding of providers and CRDs
- Resource overhead higher than lightweight alternatives due to dynamic discovery features
- Debugging routing issues can be challenging in large, complex environments
- Limited standalone static configuration options compared to traditional proxies
- Dependency on orchestrator APIs may introduce single points of failure
Reference Pages
- Traefik Official Website
- Traefik Documentation
- Traefik GitHub Repository
- Traefik Labs
- Traefik Community Forum
Code Examples
Installation and Basic Setup
# Install with Docker
docker run -d \
--name traefik \
-p 80:80 \
-p 443:443 \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
traefik:v3.4 \
--api.insecure=true \
--providers.docker=true \
--providers.docker.exposedbydefault=false \
--entrypoints.web.address=:80 \
--entrypoints.websecure.address=:443
# Install with Kubernetes Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik
# Install binary on Linux
curl -L https://github.com/traefik/traefik/releases/download/v3.4.1/traefik_v3.4.1_linux_amd64.tar.gz | tar -xzf -
sudo mv traefik /usr/local/bin/
sudo chmod +x /usr/local/bin/traefik
# Verify installation
traefik version
Basic Configuration (traefik.yml)
# Static configuration
global:
checkNewVersion: false
sendAnonymousUsage: false
api:
dashboard: true
debug: true
entryPoints:
web:
address: ":80"
http:
redirections:
entrypoint:
to: websecure
scheme: https
websecure:
address: ":443"
http3:
enabled: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-network
file:
filename: /etc/traefik/dynamic.yml
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /certs/acme.json
httpChallenge:
entryPoint: web
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 60
log:
level: INFO
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"
format: json
HTTPS Configuration and SSL Management
# ACME configuration for multiple certificate resolvers
certificatesResolvers:
letsencrypt-http:
acme:
email: [email protected]
storage: /certs/acme-http.json
httpChallenge:
entryPoint: web
letsencrypt-dns:
acme:
email: [email protected]
storage: /certs/acme-dns.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
letsencrypt-staging:
acme:
email: [email protected]
storage: /certs/acme-staging.json
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
httpChallenge:
entryPoint: web
# Dynamic configuration (dynamic.yml)
tls:
options:
default:
minVersion: "VersionTLS12"
maxVersion: "VersionTLS13"
sslStrategies:
- "tls.SniStrict"
cipherSuites:
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- "TLS_RSA_WITH_AES_256_GCM_SHA384"
strict:
minVersion: "VersionTLS13"
sslStrategies:
- "tls.SniStrict"
clientAuth:
caFiles:
- /certs/ca.pem
clientAuthType: RequireAndVerifyClientCert
# Custom certificates
certificates:
- certFile: /certs/custom.crt
keyFile: /certs/custom.key
stores:
- default
Performance Optimization and Load Balancing
# Advanced load balancing configuration
http:
services:
api-load-balancer:
loadBalancer:
servers:
- url: "http://api-1:3000"
- url: "http://api-2:3000"
- url: "http://api-3:3000"
# Load balancing algorithm
passHostHeader: true
responseForwarding:
flushInterval: 100ms
healthCheck:
path: /health
interval: 30s
timeout: 5s
hostname: api.internal
scheme: http
headers:
X-Health-Check: "traefik"
# Sticky sessions
sticky:
cookie:
name: "traefik-session"
secure: true
httpOnly: true
sameSite: "lax"
# Weighted Round Robin
weighted-service:
weighted:
services:
- name: api-v1
weight: 80
- name: api-v2
weight: 20
# Circuit breaker configuration
serversTransport:
default:
maxIdleConnsPerHost: 200
forwardingTimeouts:
dialTimeout: 30s
responseHeaderTimeout: 60s
idleConnTimeout: 90s
# Connection pooling
disableHTTP2: false
custom:
insecureSkipVerify: true
rootCAs:
- /certs/ca.pem
certificates:
- certFile: /certs/client.crt
keyFile: /certs/client.key
Security Configuration and Middleware
# Security middleware configuration
http:
middlewares:
# Security headers
security-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsSeconds: 31536000
stsPreload: true
customFrameOptionsValue: "SAMEORIGIN"
customRequestHeaders:
X-Forwarded-Proto: "https"
customResponseHeaders:
X-Robots-Tag: "noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
server: ""
# Rate limiting
api-rate-limit:
rateLimit:
burst: 100
period: 1m
sourceCriterion:
ipStrategy:
depth: 2
excludedIPs:
- "127.0.0.1/32"
- "192.168.0.0/16"
# IP allowlist
internal-only:
ipAllowList:
sourceRange:
- "192.168.1.0/24"
- "10.0.0.0/8"
- "172.16.0.0/12"
# Basic authentication
basic-auth:
basicAuth:
users:
- "admin:$2y$12$..." # htpasswd generated hash
- "user:$2y$12$..."
realm: "Restricted Area"
# Forward authentication
oauth-auth:
forwardAuth:
address: "http://oauth2-proxy:4180"
authResponseHeaders:
- "X-Auth-User"
- "X-Auth-Email"
- "X-Auth-Groups"
trustForwardHeader: true
# Request/Response modification
api-headers:
headers:
customRequestHeaders:
X-API-Version: "v2"
X-Client-ID: "traefik"
customResponseHeaders:
X-API-Server: "traefik-lb"
Access-Control-Allow-Origin: "*"
# Applying middleware to routes
routers:
secure-api:
rule: "Host(`api.example.com`)"
entryPoints:
- websecure
middlewares:
- security-headers
- api-rate-limit
- oauth-auth
- api-headers
service: api-load-balancer
tls:
certResolver: letsencrypt-dns
Kubernetes Integration (IngressRoute)
# Traefik IngressRoute for Kubernetes
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: webapp-ingressroute
namespace: production
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: webapp-service
port: 80
scheme: http
strategy: RoundRobin
weight: 100
nativeLB: true
middlewares:
- name: security-headers
- name: rate-limit
tls:
certResolver: letsencrypt
domains:
- main: app.example.com
sans:
- www.app.example.com
---
# Middleware definitions
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: security-headers
namespace: production
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: rate-limit
namespace: production
spec:
rateLimit:
burst: 100
period: 1m
---
# TCP routing for databases
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: postgres-tcp
namespace: production
spec:
entryPoints:
- postgres-tcp
routes:
- match: HostSNI(`*`)
services:
- name: postgres-service
port: 5432
proxyProtocol:
version: 2
---
# UDP routing for DNS
apiVersion: traefik.io/v1alpha1
kind: IngressRouteUDP
metadata:
name: dns-udp
namespace: kube-system
spec:
entryPoints:
- dns
routes:
- services:
- name: coredns
port: 53
Observability and Monitoring
# Comprehensive observability configuration
metrics:
prometheus:
addEntryPointsLabels: true
addServicesLabels: true
addRoutersLabels: true
buckets:
- 0.1
- 0.3
- 1.2
- 5.0
- 10.0
tracing:
otlp:
http:
endpoint: "http://jaeger:14268/api/traces"
headers:
Authorization: "Bearer token"
grpc:
endpoint: "jaeger:14250"
insecure: true
serviceName: "traefik"
sampleRate: 1.0
globalTags:
environment: "production"
datacenter: "us-east-1"
# Structured logging
log:
level: INFO
format: json
filePath: "/var/log/traefik/traefik.log"
accessLog:
format: json
filePath: "/var/log/traefik/access.log"
filters:
statusCodes: ["400-499", "500-599"]
retryAttempts: true
minDuration: "10ms"
fields:
defaultMode: keep
names:
ClientUsername: drop
ClientHost: keep
ClientPort: drop
headers:
defaultMode: keep
names:
User-Agent: keep
Authorization: drop
Content-Type: keep
# Health check endpoints
ping:
entryPoint: "traefik"
Production Deployment (Docker Compose)
# Production-ready docker-compose.yml
version: '3.8'
services:
traefik:
image: traefik:v3.4
container_name: traefik
restart: unless-stopped
command:
- "--configFile=/etc/traefik/traefik.yml"
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
- "8080:8080" # Dashboard (secure in production)
- "9100:9100" # Metrics
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik:/etc/traefik:ro"
- "traefik-certs:/certs"
- "/var/log/traefik:/var/log/traefik"
environment:
- "CF_API_EMAIL=${CLOUDFLARE_EMAIL}"
- "CF_DNS_API_TOKEN=${CLOUDFLARE_TOKEN}"
networks:
- traefik
- monitoring
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$2y$$12$$..."
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# Example application
whoami:
image: traefik/whoami:v1.8
restart: unless-stopped
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
volumes:
traefik-certs:
external: true
networks:
traefik:
external: true
monitoring:
external: true
Kubernetes Production Deployment (Helm Values)
# values.yaml for production Helm deployment
image:
tag: "v3.4.1"
deployment:
kind: DaemonSet
replicas: 3
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
ports:
web:
redirectTo: websecure
websecure:
http3:
enabled: true
tls:
enabled: true
metrics:
port: 9100
providers:
kubernetesIngress:
enabled: true
ingressClass: traefik
publishedService:
enabled: true
kubernetesCRD:
enabled: true
ingressClass: traefik
allowCrossNamespace: true
kubernetesGateway:
enabled: true
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /data/acme.json
dnsChallenge:
provider: route53
delayBeforeCheck: 60s
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
persistence:
enabled: true
size: 128Mi
storageClass: "gp3"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 1Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
metrics:
prometheus:
service:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
logs:
general:
level: INFO
access:
enabled: true
format: json
globalArguments:
- "--global.sendanonymoususage=false"
- "--entrypoints.websecure.http.tls.options=default@file"
- "--providers.file.filename=/data/dynamic_conf.yml"
- "--ping.entrypoint=traefik"
nodeSelector:
node-role.kubernetes.io/worker: "true"
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- traefik
topologyKey: kubernetes.io/hostname