traefik
Installation
SKILL.md
Identity
- Docker image:
traefik:v3(current stable;traefik:latesttracks major version) - Binary install:
/usr/local/bin/traefik(when running outside Docker) - Static config:
/etc/traefik/traefik.yml(ortraefik.toml; YAML preferred) - Dynamic config dir:
/etc/traefik/dynamic/(watched by file provider) - Docker socket:
/var/run/docker.sock(mounted read-only into the Traefik container) - Dashboard port:
8080/tcp(default; disable or protect in production) - Logs: Docker:
docker logs traefik; Systemd:journalctl -u traefik - Distro install:
apt install traefik/ download binary from https://github.com/traefik/traefik/releases
Key Operations
| Operation | Command |
|---|---|
| Check dashboard (browser) | http://localhost:8080/dashboard/ (trailing slash required) |
| API: list routers | curl -s http://localhost:8080/api/http/routers | jq '.[].name' |
| API: list services | curl -s http://localhost:8080/api/http/services | jq '.[].name' |
| API: list middlewares | curl -s http://localhost:8080/api/http/middlewares | jq '.[].name' |
| API: check router detail | curl -s http://localhost:8080/api/http/routers/<name>@docker | jq . |
| API: check TLS certs | curl -s http://localhost:8080/api/tls/certificates | jq '.[].domain' |
| Reload config (Docker) | Traefik watches Docker socket and file provider — no manual reload needed |
| Reload config (binary) | kill -HUP $(pidof traefik) — reloads dynamic config only |
| Restart container | docker restart traefik |
| Test static config syntax | traefik version then traefik --configfile /etc/traefik/traefik.yml --dry-run (v3 supports --dry-run for static config validation) |
| Enable debug logging | Set log.level: DEBUG in static config, restart |
| Healthcheck endpoint | curl -s http://localhost:8080/ping → OK |
| View Docker provider state | curl -s http://localhost:8080/api/providers/docker | jq . |
| View file provider state | curl -s http://localhost:8080/api/providers/file | jq . |
| Check entrypoints | curl -s http://localhost:8080/api/entrypoints | jq '.[].name' |
| View TCP routers | curl -s http://localhost:8080/api/tcp/routers | jq '.[].name' |
Expected Ports
80/tcp— web entrypoint (HTTP)443/tcp— websecure entrypoint (HTTPS)8080/tcp— dashboard/API (disable or restrict in production)- Verify:
ss -tlnp | grep traefikordocker port traefik - Firewall:
sudo ufw allow 80,443/tcp(do NOT expose 8080 publicly without auth)
Health Checks
curl -sf http://localhost:8080/ping→OKcurl -sI http://localhost→ HTTP response, notConnection refusedcurl -s http://localhost:8080/api/http/routers | jq 'length'→ count > 0docker logs traefik 2>&1 | grep -i error | tail -20→ no unexpected errors
Common Failures
| Symptom | Likely cause | Check/Fix |
|---|---|---|
404 page not found |
No router rule matches the request | Check Host label on the container; verify rule syntax in router; confirm entrypoint is listed |
| Dashboard shows router but 404 in browser | Router has no service, or service has no healthy backend | Check service definition; container must be running |
Gateway Timeout / no response |
Container not reachable on its port | Verify container is on the same Docker network as Traefik; check traefik.http.services.<n>.loadbalancer.server.port label |
Entrypoint not defined |
Router references entrypoint not in static config | Entrypoints are static — add to traefik.yml and restart |
| Docker socket permission denied | Traefik container can't read the socket | Mount /var/run/docker.sock:/var/run/docker.sock:ro; check socket group; or run as root in container |
ACME: too many certificates already issued |
Hit Let's Encrypt rate limit | Switch to staging CA (caServer: https://acme-staging-v02.api.letsencrypt.org/directory) while debugging |
| ACME: cert never issued | HTTP challenge blocked | Port 80 must reach Traefik publicly; check firewall, NAT, and DNS |
| Middleware not applied | Wrong middleware name or missing @provider suffix |
Use traefik.http.routers.<n>.middlewares=name@docker for Docker-defined middlewares |
| TLS passthrough vs termination confusion | Using passthrough: true when you want Traefik to terminate TLS |
Passthrough routes raw TCP — no headers injected, no cert management. For termination, omit passthrough |
certificate not trusted in browser |
Staging ACME cert in production | Switch caServer to production URL and delete acme.json to re-issue |
acme.json permission error |
Wrong file permissions | chmod 600 /letsencrypt/acme.json — ACME storage must not be world-readable |
Pain Points
- Static vs dynamic config split:
entrypoints,providers,certificatesResolvers, andlogare static — they require a Traefik restart to change. Routers, services, and middlewares are dynamic — Traefik reloads them automatically. Confusing the two is the most common source of "my change did nothing" bugs. - Entrypoints are static-only: You cannot define a new entrypoint via a Docker label or file provider. Add them to
traefik.ymland restart. - Docker labels are dynamic config: They are re-evaluated automatically as containers start/stop. No restart needed for label changes — but the container itself must restart.
- ACME requires persistent storage:
acme.jsonmust survive Traefik restarts. Use a named Docker volume or a bind-mounted path. Losing it forces re-issuance and may hit rate limits. - Dashboard has no auth by default: With
api.insecure: true, anyone who can reach port 8080 sees your full routing config. Always protect it with a middleware or bind to127.0.0.1:8080in production. - Traefik v2 vs v3 differences: v3 removes the
pilotsection, changes some middleware names (e.g.,ReplacePathRegexcapitalization), and introduces the Hub integration. Docker Compose examples online are often v2 — check theimage:tag before copying. exposedByDefault: falseis the safe default: Withtrue, every container gets a router — including databases and internal services. Set tofalseand opt in withtraefik.enable=true.@providersuffix in cross-provider references: A middleware defined via Docker labels isname@docker. If a file-provider router references it, the full namename@dockeris required.
References
See references/ for:
traefik.yml.annotated— full static config with every directive explained, plus a dynamic config examplecommon-patterns.md— Docker Compose setup, label-based routing, HTTPS, middlewares, TCP, load balancing, and file provider examplesdocs.md— official documentation links
Related skills