Traefik
Cloud-native reverse proxy and load balancer
Traefik is a modern reverse proxy and load balancer that automatically discovers services and configures routing. It integrates natively with Docker, Kubernetes, and other orchestrators.
Traefik setup guides & articles
Hands-on coverage of Traefik from the blog.
Key features
- Automatic service discovery
- Native Docker and Kubernetes support
- Let's Encrypt integration
- Live configuration reload
Pros & cons
Strengths
- Automatic service discovery
- Built-in Let's Encrypt
- First-class Docker support
Trade-offs
- Configuration learning curve
- Debugging can be opaque
Traefik replaces
Last reviewed Aug 26, 2026 · 833 words
Traefik earns its place only if you add and remove Docker services often enough that writing proxy config by hand is a chore. Past roughly 5 containers and 1 new one a month, its label-driven routing pays back the learning curve; below that, Caddy gets you to HTTPS in 3 lines and you should stop reading. The catalogue rates Traefik Medium difficulty on 128 MB of RAM, and both numbers are honest: it is light to run and awkward to learn, mostly because there are two configs and the docs do not shout about which is which.
Static and dynamic config are different files, and mixing them is mistake number one
Static configuration (entrypoints, providers, certificate resolvers) is read once at start from traefik.yml or command-line flags. Dynamic configuration (routers, services, middlewares) comes from providers at runtime, and on a Docker host that means container labels. Put a router in traefik.yml and it is silently ignored; put an entrypoint in a label and same result. Almost every "Traefik does nothing" thread on the forums is one of those two.
The static file I start every host from:
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
network: proxy
certificatesResolvers:
le:
acme:
email: [email protected]
storage: /acme.json
tlsChallenge: {}
exposedByDefault: false is the line worth underlining. Without it, every container on the host gets a route whether you asked or not, including the database you never meant to publish. With it, nothing is exposed until you say so, per container.
Traefik itself is 15 lines of compose
services:
traefik:
image: traefik:v3
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./acme.json:/acme.json
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
restart: unless-stopped
networks:
proxy:
external: true
Create the network once with docker network create proxy, and create the certificate store with touch acme.json && chmod 600 acme.json. Traefik refuses to write certificates to a file with looser permissions and logs a single line about it, which is easy to miss.
The socket mount is the uncomfortable part. Read-only access to the Docker socket is still root-equivalent on the host; anyone who compromises Traefik can start containers. The mitigations are a socket-proxy container that filters the Docker API, or running Traefik on a dedicated host. For a home server behind a firewall I accept the risk and keep Traefik updated; for anything with untrusted users I would not.
Four labels expose a service
Every service you want published needs, at minimum:
services:
whoami:
image: traefik/whoami
networks:
- proxy
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=le
The container must join the proxy network or Traefik cannot reach it. If the image exposes more than 1 port, add traefik.http.services.whoami.loadbalancer.server.port=8080 (whatever the app listens on) or Traefik picks one and you get a 502 that looks like a certificate problem. Those two conditions, plus a missing enable=true, account for the bulk of the debugging sessions I have sat through.
Debugging is opaque until you turn the lights on
The catalogue's "debugging can be opaque" con is fair. Out of the box Traefik logs almost nothing, and a router that failed to build produces a 404 with no explanation. Two settings fix that: log.level: DEBUG in the static file while you are setting things up, and the dashboard. Enable it with api.dashboard: true, then route it through Traefik itself with a basic-auth middleware rather than opening port 8080 with api.insecure=true, which puts an unauthenticated control panel on your LAN. The dashboard shows every router, its rule, and a red error badge when a label is malformed, which is the fastest way to find a stray backtick.
Certificates deserve their own line. If acme.json stays empty, check the file permissions first, the DNS record second, and whether the port is actually reachable from the internet third. The TLS challenge needs 443 open and the HTTP challenge needs 80; behind CGNAT neither works and you need the DNS challenge with an API token for your DNS provider. The certificates guide covers the DNS route.
What I'd do
On a Docker host with more than a handful of services, Traefik with the static file above, exposedByDefault off, the dashboard behind basic auth, and a Git repo holding every compose file so the labels are versioned. Add the DEBUG log level on day one and remove it on day three. If your host runs 3 containers and will stay that way, take the Caddy versus Traefik decision the other way; the reverse proxy showdown is the longer form of that argument.
Compare Traefik
11 head-to-head comparisons.
Similar reverse proxy & gateways apps
Caddy
Reverse Proxy & GatewaysFast, multi-platform web server with automatic HTTPS
Replaces Nginx, Apache
Pi-hole
Reverse Proxy & GatewaysBlackhole for Internet advertisements with a GUI for management
Replaces NextDNS
acme.sh
Reverse Proxy & GatewaysPure shell ACME client for TLS certificates
Replaces Certbot
mitmproxy
Reverse Proxy & GatewaysInteractive HTTPS proxy for inspection and debugging
Replaces Charles Proxy, Fiddler
Kong Gateway
Reverse Proxy & GatewaysCloud-native, fast, scalable API gateway
Replaces AWS API Gateway, Apigee
Istio
Reverse Proxy & GatewaysFull-featured service mesh for traffic and security control
Replaces AWS App Mesh