TL;DR
Traefik is a modern, cloud-native reverse proxy and load balancer that automatically discovers services from Docker, Kubernetes, and other orchestrators. Unlike Nginx or Apache, Traefik dynamically configures itself by watching your infrastructure β when a container starts, Traefik detects it and routes traffic automatically via labels. It provides automatic HTTPS via Let's Encrypt, built-in middlewares for rate limiting, authentication, and header manipulation, plus a real-time dashboard. Traefik v3 (current stable) adds native WebAssembly plugin support, OpenTelemetry tracing, and HTTP/3. For container-based and microservices architectures in 2026, Traefik is the go-to edge router.
Key Takeaways
- Traefik auto-discovers services from Docker, Kubernetes, Consul, and other providers β no manual config file updates needed
- Docker labels define routing rules directly on containers, keeping infrastructure config co-located with services
- Automatic HTTPS with Let's Encrypt via HTTP or DNS challenge, with wildcard certificate support
- Built-in middlewares handle rate limiting, basic auth, IP whitelisting, circuit breakers, retry, and headers
- Kubernetes IngressRoute CRD provides full Traefik feature access beyond standard Ingress resources
- Traefik v3 brings HTTP/3, OpenTelemetry, WASM plugins, and improved performance over v2
Traefik (pronounced "traffic") is an open-source edge router and reverse proxy designed for cloud-native environments. Created by Traefik Labs, it has become the most popular reverse proxy for Docker and Kubernetes workloads, with over 53,000 GitHub stars and billions of downloads. Traefik's key innovation is automatic service discovery: it watches your infrastructure and dynamically generates routing configuration. This comprehensive guide covers everything from basic Docker setups to production-grade Kubernetes ingress with Traefik v3.
What Is Traefik and Why It Is the Cloud-Native Reverse Proxy
Traefik is a modern HTTP reverse proxy and load balancer that integrates natively with container orchestrators and service discovery systems. Unlike traditional reverse proxies where you manually define upstream servers in config files, Traefik connects directly to your infrastructure APIs and automatically creates routes for your services.
When you start a Docker container with appropriate labels, Traefik immediately detects it and begins routing traffic β no reload, no restart, no manual configuration. When the container stops, Traefik removes the route. This dynamic behavior makes Traefik ideal for environments where services are constantly scaling.
- Automatic service discovery from Docker, Kubernetes, Consul, etcd, and more
- Dynamic configuration β routes update in real-time as services change
- Automatic HTTPS with Let's Encrypt (HTTP and DNS challenge)
- Built-in load balancing with round robin, weighted, and sticky session strategies
- Rich middleware ecosystem: rate limiting, auth, headers, circuit breaker, retry
- TCP and UDP routing support for non-HTTP protocols
- Real-time dashboard and Prometheus/OpenTelemetry metrics
Traefik vs Nginx vs Caddy vs HAProxy
Each reverse proxy has strengths suited to different architectures. This comparison helps you decide which fits your infrastructure.
| Feature | Traefik | Nginx | Caddy | HAProxy |
|---|---|---|---|---|
| Auto service discovery | Native (Docker, K8s, Consul) | Manual config reload | Limited (Docker labels) | Manual / consul-template |
| Automatic HTTPS | Built-in (ACME) | Manual (certbot) | Built-in (zero config) | Manual (certbot) |
| Config approach | YAML/TOML + labels/CRDs | nginx.conf (static) | Caddyfile (simple) | haproxy.cfg (static) |
| Docker integration | Excellent (native labels) | Manual config | Good (labels via plugin) | Manual config |
| Kubernetes support | IngressRoute CRD + Ingress | Ingress Controller | Basic Ingress | Ingress Controller |
| Load balancing | Round robin, weighted, sticky | Round robin, weighted, IP hash | Round robin, random, least_conn | Advanced (many algorithms) |
| Middleware system | Built-in (20+ middlewares) | Modules (compile-time) | Directives + plugins | ACLs and stick tables |
| Built-in dashboard | Yes (built-in) | No (Nginx Plus only) | No | Yes (stats page) |
| HTTP/3 support | Experimental (v3) | Experimental | Native (default) | Not supported |
| Written in | Go | C | Go | C |
Installation
Traefik can be deployed via Docker, Kubernetes Helm chart, binary download, or package managers.
Docker (Most Common)
# Pull official Traefik v3 image
docker pull traefik:v3.2
# Run Traefik with Docker provider
docker run -d --name traefik \
-p 80:80 -p 443:443 -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ./traefik.yml:/etc/traefik/traefik.yml \
-v ./acme.json:/acme.json \
traefik:v3.2Kubernetes 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 \
-f traefik-values.ymlBinary Download
# Download from GitHub releases (Linux amd64)
curl -LO https://github.com/traefik/traefik/releases/download/v3.2.0/traefik_v3.2.0_linux_amd64.tar.gz
tar xzf traefik_v3.2.0_linux_amd64.tar.gz
sudo mv traefik /usr/local/bin/ && traefik version
# macOS: brew install traefik
# Windows: choco install traefikCore Concepts: Entrypoints, Routers, Services, Middlewares, Providers
Traefik has five core concepts that work together to route traffic.
# Traefik Architecture Flow:
# Internet β [Entrypoints] β [Routers] β [Middlewares] β [Services] β Backend
# [Providers] watch Docker/K8s/Consul and auto-configure the above- Entrypoints: Entrypoints are network ports where Traefik listens for incoming traffic (e.g., port 80 for HTTP, port 443 for HTTPS).
- Routers: Routers analyze incoming requests (host, path, headers) and determine which service should handle them. Routers connect entrypoints to services and can attach middlewares.
- Services: Services represent the actual backend applications. They define how to reach backend servers and which load balancing strategy to use.
- Middlewares: Middlewares modify requests or responses before they reach the service β authentication, rate limiting, headers, path stripping, and more.
- Providers: Providers are infrastructure components that Traefik watches for service discovery. Docker, Kubernetes, Consul, and file are providers.
Docker Provider: Auto-Discovery via Labels
The Docker provider is Traefik's most popular feature. Traefik connects to the Docker socket, watches for container events, and automatically creates routes based on container labels.
# traefik.yml β static configuration
api:
dashboard: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-public
# Docker labels for a container:
# - "traefik.enable=true"
# - "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
# - "traefik.http.routers.myapp.entrypoints=websecure"
# - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
# - "traefik.http.services.myapp.loadbalancer.server.port=3000"
# - "traefik.http.routers.myapp.middlewares=my-ratelimit,my-headers"Docker Compose Examples
Docker Compose is the most common way to run Traefik. Here are production-ready examples.
Traefik with HTTPS
# docker-compose.yml β Traefik with automatic HTTPS
services:
traefik:
image: traefik:v3.2
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:\$\$apr1\$\$xyz\$\$hash"
networks:
traefik-public:
external: trueMulti-Service Stack
# docker-compose.yml β Multi-service stack with Traefik
services:
frontend:
image: node:20-alpine
networks: [traefik-public]
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`app.example.com`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
api:
image: golang:1.23-alpine
networks: [traefik-public, backend]
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=8080"
- "traefik.http.routers.api.middlewares=api-ratelimit"
- "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"
db:
image: postgres:16-alpine
volumes: [db-data:/var/lib/postgresql/data]
networks: [backend] # Not exposed to Traefik
volumes:
db-data:
networks:
traefik-public:
external: true
backend:Automatic HTTPS with Let's Encrypt
Traefik can automatically obtain and renew TLS certificates from Let's Encrypt using the ACME protocol.
HTTP Challenge
# traefik.yml β HTTP challenge (most common)
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /acme.json
httpChallenge:
entryPoint: web
# IMPORTANT: touch acme.json && chmod 600 acme.jsonDNS Challenge (Wildcard Certificates)
# traefik.yml β DNS challenge (wildcard certs)
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /acme.json
dnsChallenge:
provider: cloudflare
resolvers: ["1.1.1.1:53", "8.8.8.8:53"]
# Env: CF_API_EMAIL + CF_DNS_API_TOKEN
# Label: traefik.http.routers.app.tls.domains[0].main=example.com
# Label: traefik.http.routers.app.tls.domains[0].sans=*.example.comLoad Balancing Strategies
Traefik supports multiple load balancing strategies to distribute traffic across backend instances.
# File provider β weighted load balancing + sticky sessions
http:
services:
my-service:
weighted:
services:
- name: v1
weight: 80
- name: v2
weight: 20
v1:
loadBalancer:
servers:
- url: "http://v1-app:8080"
v2:
loadBalancer:
servers:
- url: "http://v2-app:8080"
# Sticky sessions via Docker labels:
# traefik.http.services.myapp.loadbalancer.sticky.cookie=true
# traefik.http.services.myapp.loadbalancer.sticky.cookie.name=server_idMiddlewares: Rate Limiting, Auth, Headers, and More
Middlewares intercept and modify requests/responses between the router and the service.
Rate Limiting
# Rate limiting β Docker labels
- "traefik.http.middlewares.my-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.my-ratelimit.ratelimit.burst=50"
- "traefik.http.middlewares.my-ratelimit.ratelimit.period=1m"Basic Authentication
# Basic auth: htpasswd -nb admin secure-password
# Docker label (double $$ to escape in compose):
- "traefik.http.middlewares.my-auth.basicauth.users=admin:\$\$apr1\$\$xyz\$\$hash"
# File provider:
http:
middlewares:
my-auth:
basicAuth:
users: ["admin:$apr1$xyz$hash"]
removeHeader: trueSecurity Headers
# Security headers middleware
http:
middlewares:
secure-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: trueStrip Prefix
# Strip prefix β /api/v1/* becomes /* at backend
- "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api/v1"
- "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api/v1`)"Circuit Breaker
# Circuit breaker β stop routing to failing backends
http:
middlewares:
my-cb:
circuitBreaker:
expression: "NetworkErrorRatio() > 0.30 || ResponseCodeRatio(500, 600, 0, 600) > 0.25"
checkPeriod: 10s
fallbackDuration: 30sKubernetes Ingress Controller and IngressRoute CRD
Traefik is one of the most popular Kubernetes ingress controllers. It supports both standard Ingress resources and its own IngressRoute CRD.
IngressRoute CRD
# Traefik IngressRoute CRD
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app-route
spec:
entryPoints: [websecure]
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
middlewares:
- name: my-ratelimit
- match: Host(`api.example.com`) && PathPrefix(`/v1`)
kind: Rule
services:
- name: my-api
port: 8080
tls:
certResolver: letsencryptKubernetes Middleware CRD
# Kubernetes Middleware CRD
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-ratelimit
spec:
rateLimit:
average: 100
burst: 50
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
spec:
headers:
stsSeconds: 31536000
frameDeny: true
contentTypeNosniff: trueFile Provider for Static Configuration
The file provider allows you to define routers, services, and middlewares in YAML or TOML files for external services not managed by Docker or Kubernetes.
# traefik.yml β enable file provider
providers:
file:
filename: /etc/traefik/dynamic.yml
watch: true
# dynamic.yml β external service routing
http:
routers:
external-app:
rule: "Host(`external.example.com`)"
service: external-app
entryPoints: [websecure]
tls:
certResolver: letsencrypt
services:
external-app:
loadBalancer:
servers:
- url: "http://192.168.1.100:8080"
healthCheck:
path: /health
interval: 10sTraefik Dashboard (Secure Setup)
Traefik includes a built-in web dashboard showing all routers, services, middlewares, and their health status. Always secure it with authentication in production.
# Secure dashboard via Docker labels
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "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:\$\$apr1\$\$hash"Health Checks and Circuit Breakers
Traefik supports active health checks to verify backend servers are healthy. Combined with circuit breakers, this provides resilient routing.
# Health checks in file provider
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://app1:8080"
- url: "http://app2:8080"
healthCheck:
path: /health
interval: 10s
timeout: 3sTCP and UDP Routing
Traefik can route non-HTTP traffic using TCP and UDP routers β useful for databases, message queues, DNS servers, and other protocols.
# TCP/UDP routing in traefik.yml + dynamic.yml
entryPoints:
postgres:
address: ":5432"
dns-udp:
address: ":53/udp"
# dynamic.yml
tcp:
routers:
postgres-route:
entryPoints: [postgres]
rule: "HostSNI(`db.example.com`)"
service: postgres-svc
tls: { passthrough: true }
services:
postgres-svc:
loadBalancer:
servers:
- address: "db-primary:5432"
udp:
routers:
dns-route:
entryPoints: [dns-udp]
service: dns-svc
services:
dns-svc:
loadBalancer:
servers:
- address: "coredns:53"Traefik v3 Features
Traefik v3 (stable since 2024) introduces significant improvements over v2.
- HTTP/3 (QUIC) support for faster connections on mobile and lossy networks
- Native OpenTelemetry integration for distributed tracing
- WebAssembly (WASM) plugin support for custom middleware without recompiling
- Kubernetes Gateway API support alongside IngressRoute CRDs
- Improved performance with connection pooling and HTTP/2 backend support
- Breaking changes: entryPoint name changes, removed deprecated options, ACME v2 required
# Traefik v3 β HTTP/3 + OpenTelemetry
entryPoints:
websecure:
address: ":443"
http3: {}
tracing:
otlp:
grpc:
endpoint: "otel-collector:4317"
insecure: true
experimental:
plugins:
my-plugin:
moduleName: "github.com/user/traefik-plugin"
version: "v1.0.0"Metrics and Monitoring: Prometheus, Grafana, Access Logs
Traefik provides comprehensive observability through Prometheus metrics, structured access logs, and distributed tracing.
# Prometheus metrics + structured access logs
metrics:
prometheus:
entryPoint: metrics
addRoutersLabels: true
addServicesLabels: true
entryPoints:
metrics:
address: ":8082"
accessLog:
filePath: "/var/log/traefik/access.log"
format: json
bufferingSize: 100
filters:
statusCodes: ["400-599"]
# Grafana: Import dashboard ID 17346 or 4475High Availability Setup
In Docker Swarm, deploy Traefik as a global service on manager nodes. Use a distributed certificate store (Consul, etcd, Redis) so all instances share certificates.
In Kubernetes, the Helm chart deploys multiple Traefik pods by default. Certificate management is handled via cert-manager or Traefik's built-in ACME with a shared storage backend.
# Kubernetes HA β Helm values
deployment:
replicas: 3
resources:
requests: { cpu: 200m, memory: 128Mi }
limits: { cpu: 1000m, memory: 512Mi }
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: traefik
topologyKey: kubernetes.io/hostnamePerformance Tuning
Traefik performs well out of the box, but high-traffic deployments benefit from tuning.
- Increase entrypoint transport lifecycle grace period for graceful shutdowns under load
- Enable HTTP/2 between Traefik and backends with serversTransport for multiplexed connections
- Configure connection keep-alive and idle timeout to match backend capabilities
- Set appropriate maxIdleConnsPerHost for backend connection pooling
- Use access log buffering (bufferingSize) to reduce I/O overhead
- Deploy Traefik on dedicated nodes in Kubernetes to avoid resource contention
# Performance tuning
entryPoints:
websecure:
address: ":443"
transport:
lifeCycle: { graceTimeOut: 30s }
respondingTimeouts:
readTimeout: 60s
writeTimeout: 60s
idleTimeout: 180s
serversTransport:
maxIdleConnsPerHost: 200
forwardingTimeouts:
dialTimeout: 5s
responseHeaderTimeout: 30sSecurity Best Practices
Securing your Traefik deployment is critical since it sits at the edge of your network.
- Never expose the dashboard without authentication β use basicAuth or forwardAuth middleware
- Mount the Docker socket read-only (ro) or use a Docker socket proxy like Tecnativa/docker-socket-proxy
- Set security headers on all routes: HSTS, X-Frame-Options, X-Content-Type-Options, CSP
- Use TLS 1.2+ minimum version and restrict cipher suites in TLS options
- Enable access logs for audit trails and integrate with SIEM systems
- Implement rate limiting on all public-facing routes to prevent abuse
# TLS options β strong cipher suites
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
sniStrict: trueCommon Patterns: Canary, Blue-Green, A/B Testing
Traefik's weighted load balancing and middleware system enable advanced deployment patterns including canary (route a small percentage to a new version), blue-green (maintain two identical environments and switch instantly), and A/B testing (route based on headers or cookies).
# Canary deployment β 90% stable, 10% canary
http:
services:
my-app-canary:
weighted:
services:
- name: stable
weight: 90
- name: canary
weight: 10
stable:
loadBalancer:
servers:
- url: "http://app-v1:8080"
canary:
loadBalancer:
servers:
- url: "http://app-v2:8080"
# Blue-green β switch by changing weights to 0/100
blue-green:
weighted:
services:
- name: blue
weight: 100
- name: green
weight: 0 # Change to 100 to switch
# A/B testing β route based on headers
routers:
app-v2:
rule: "Host(`app.example.com`) && HeadersRegexp(`X-AB-Test`, `v2`)"
service: app-v2
priority: 100
app-default:
rule: "Host(`app.example.com`)"
service: app-v1
priority: 50Troubleshooting Guide
- 404 Not Found: Check traefik labels, Docker network, and Host rule match.
- 502 Bad Gateway: Backend unreachable β verify container, port, and health checks.
- Certificate not issued: Ensure ports 80/443 accessible. Check ACME with --log.level=DEBUG.
- Dashboard not loading: Verify api.dashboard=true and correct entrypoints/auth.
- Middleware not applying: Names are case-sensitive and must match the provider namespace.
- Docker labels not detected: Ensure Docker socket access and explicit Docker network.
- Slow responses: Check backend health, enable access logging, verify connection pooling.
- WebSocket not connecting: Ensure no middleware strips the Upgrade header.
# Debug Traefik
log:
level: DEBUG
# docker logs -f traefik
# curl http://localhost:8080/api/rawdata | jq .
# cat acme.json | jq ".letsencrypt.Certificates"
# docker network inspect traefik-publicFrequently Asked Questions
When should I choose Traefik over Nginx?
Choose Traefik when running Docker or Kubernetes workloads where services are frequently deployed, scaled, or removed. Traefik's automatic service discovery eliminates manual config file updates. Choose Nginx for static infrastructure, maximum raw performance, or Lua scripting (OpenResty).
Is Traefik production-ready?
Yes. Traefik is used in production by thousands of companies. The v3 stable release provides mature features including automatic HTTPS, health checks, circuit breakers, and comprehensive monitoring.
How does Traefik handle automatic HTTPS?
Traefik uses the ACME protocol to obtain and renew certificates from Let's Encrypt. It supports HTTP challenge (port 80 must be accessible) and DNS challenge (for wildcard certificates). Certificates are stored in acme.json and renewed automatically before expiry.
Can Traefik replace HAProxy for load balancing?
For most container-based workloads, yes. Traefik supports round robin, weighted, and sticky session load balancing with health checks. However, HAProxy offers more advanced L4 features and higher raw throughput for extreme-scale scenarios.
How do I secure the Traefik dashboard?
Use basicAuth middleware with htpasswd-generated credentials, or forwardAuth to integrate with an external authentication provider like OAuth2 Proxy or Authelia. Never expose the dashboard without authentication.
Does Traefik support gRPC?
Yes. Traefik natively supports gRPC over HTTP/2. Configure your service with h2c scheme for unencrypted gRPC or standard HTTPS for encrypted gRPC. Traefik handles gRPC load balancing and health checking.
What is the difference between Traefik v2 and v3?
Traefik v3 adds HTTP/3 (QUIC), native OpenTelemetry tracing, WebAssembly plugin support, Kubernetes Gateway API, and improved performance. It includes breaking changes: renamed entrypoints, removed deprecated v1 options, and requires ACME v2.
How does Traefik compare to Caddy?
Both are Go-based reverse proxies with automatic HTTPS. Traefik excels at container orchestration with native Docker/Kubernetes integration. Caddy excels at simplicity with Caddyfile and zero-config HTTPS. For Docker/K8s, choose Traefik. For simpler deployments, choose Caddy.