Traefik v3 Reverse Proxy: Complete Self-Hosting Setup Guide (2026)
Traefik is a reverse proxy that discovers services from Docker labels and config files, issues Let's Encrypt certificates automatically, and handles HTTP/3. Version 3 refines middleware syntax and improves performance. This guide covers installation, your first service, middleware for auth and rate limiting, and dashboard security on a Liquid Web VPS.
What Is Traefik?
Traefik is an auto-discovering reverse proxy. Unlike Nginx, you don't edit a config file for each new service — you add Docker labels or file-based config, and Traefik picks them up. It integrates with Let's Encrypt for SSL and supports HTTP/3 (QUIC).
Traefik v3 changes from v2:
- Cleaner middleware syntax
- Better HTTP/3 support
- Improved performance
- Refined plugin architecture
Docker Compose Setup
Create docker-compose.yml:
services:
traefik:
image: traefik:v3.2
restart: unless-stopped
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--accesslog=true"
- "--accesslog.filepath=/var/log/traefik/access.log"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-letsencrypt:/letsencrypt
- traefik-logs:/var/log/traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$..."
networks:
- traefik
volumes:
traefik-letsencrypt:
traefik-logs:
networks:
traefik:
external: true
Create the network:
docker network create traefik
Generate BasicAuth hash for the dashboard:
docker run --rm httpd:alpine htpasswd -nbB admin yourpassword
# Copy the output (e.g. admin:$apr1$...) and use in the basicauth label.
# Escape $ as $$ in docker-compose.
Configuration File (Optional)
For more control, use a static config file traefik.yml:
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: you@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: /etc/traefik/dynamic
watch: true
Mount traefik.yml and a dynamic/ directory for dynamic config (middleware, routers).
Adding Your First Service
Start a simple web app and add Traefik labels:
services:
whoami:
image: traefik/whoami
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
- traefik
networks:
traefik:
external: true
Point whoami.yourdomain.com to your server. Traefik will fetch a certificate and route HTTPS traffic to the container.
Middleware: BasicAuth, Rate Limiting, Headers
BasicAuth — protect a service:
labels:
- "traefik.http.middlewares.myauth.basicauth.users=admin:$$apr1$$..."
- "traefik.http.routers.myservice.middlewares=myauth"
Rate limiting:
labels:
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.ratelimit.ratelimit.burst=50"
- "traefik.http.routers.myservice.middlewares=ratelimit"
Security headers:
labels:
- "traefik.http.middlewares.secureheaders.headers.browserXSSFilter=true"
- "traefik.http.middlewares.secureheaders.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.secureheaders.headers.forceSTSHeader=true"
- "traefik.http.middlewares.secureheaders.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secureheaders.headers.stsPreload=true"
- "traefik.http.middlewares.secureheaders.headers.stsSeconds=31536000"
- "traefik.http.routers.myservice.middlewares=secureheaders"
Chain multiple middlewares: middlewares=myauth,ratelimit,secureheaders.
File-Based Dynamic Configuration
For complex setups, use the file provider. Create /etc/traefik/dynamic/middlewares.yml:
http:
middlewares:
secure-headers:
headers:
browserXssFilter: true
contentTypeNosniff: true
frameDeny: true
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
Reference it from Docker labels: traefik.http.routers.myservice.middlewares=secure-headers. The file provider watches for changes and reloads automatically. Combine with Docker discovery for a hybrid setup.
HTTP to HTTPS Redirect
Redirect all HTTP traffic to HTTPS. Add a catch-all router on the web entrypoint:
labels:
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
Dashboard Security
The dashboard exposes router and service info. Always protect it:
- BasicAuth — add
basicauthmiddleware (as in the Traefik service above). - IP whitelist —
traefik.http.middlewares.dashboard-ip.ipallowlist.sourcerange=1.2.3.4/32 - Internal only — don't expose a public host; access via
docker execor SSH tunnel.
Traefik vs Nginx Proxy Manager vs Caddy
| Feature | Traefik | Nginx Proxy Manager | Caddy |
|---|---|---|---|
| Config style | Labels, file | Web UI | Caddyfile |
| Docker discovery | Native | Manual | Manual |
| Auto SSL | Let's Encrypt | Let's Encrypt | Built-in |
| HTTP/3 | Yes | Via Nginx (newer) | Yes |
| Middleware | Rich (auth, rate limit, etc.) | Limited | Good |
| Learning curve | Medium | Low | Low |
| Best for | Docker-native setups | GUI lovers | Simplicity |
Choose Traefik when you run many Docker services and want label-based configuration. Use Liquid Web VPS for a stable host with good network performance.
When to Choose Traefik
Traefik shines when you run multiple Dockerized services and want zero-friction routing. Add a new container with a few labels — no config file edits, no reloads. Compare that to Nginx or Caddy, where each new service means editing and reloading a central config. Traefik is ideal for home labs, staging environments, and microservice stacks where services come and go frequently. For a single static site or a handful of long-lived apps, Nginx Proxy Manager's GUI might be simpler. For Docker-native setups with 5+ services, Traefik saves time and reduces config drift.
Logging and Observability
Traefik outputs access logs and metrics. Enable --accesslog=true and --accesslog.filepath as in the compose example. For Prometheus metrics, add --metrics.prometheus=true and --metrics.prometheus.entrypoint=traefik. Scrape http://traefik:8080/metrics for request counts, latency percentiles, and backend health. Combine with Grafana dashboards for full observability of your reverse proxy and backend services.
Production Checklist
Before going live with Traefik, verify: (1) ports 80 and 443 are open and forwarded if behind NAT; (2) DNS A records point to your server; (3) dashboard is protected with BasicAuth or IP allowlist; (4) HTTP redirects to HTTPS; (5) security headers middleware is attached to public services. Use a Liquid Web VPS for DDoS protection, managed backups, and 24/7 monitoring.
Troubleshooting
Certificate not issued — Ensure port 80 is reachable for HTTP-01 challenge. Check acme.json for errors. For wildcards, switch to DNS-01.
502 Bad Gateway — Container not running or wrong port. Verify loadbalancer.server.port matches the app. Ensure containers share the traefik network.
Dashboard unreachable — Enable api.dashboard=true. Add a router for the dashboard. Protect with BasicAuth before exposing.
For more Docker patterns, see Docker Compose production guide and Coolify for app deployment. Secure your host with the VPS security hardening checklist.
Deploy Traefik, add one service with labels, verify HTTPS. Then add middleware. Use file provider for shared middleware definitions.
Traefik is a reverse proxy that auto-discovers services from Docker labels. It handles Let's Encrypt SSL, HTTP/3, and middleware like BasicAuth and rate limiting.
Traefik integrates with Let's Encrypt. Set a certificate resolver (certresolver) and storage path. It uses HTTP-01 or DNS-01 challenge. Certificates renew automatically.
Add Docker labels to your container: traefik.enable=true, traefik.http.routers.NAME.rule=Host(`domain.com`), traefik.http.routers.NAME.tls.certresolver=letsencrypt, and loadbalancer port. Put the container on the Traefik network.
Add a BasicAuth middleware and attach it to the dashboard router. Or use IP allowlist. Never expose the dashboard without authentication.




