Over the years, I’ve experimented with various reverse proxy setups — from classic Nginx configurations that I used to hand-craft with care, to the clean and declarative world of Caddy, and even to the more opinionated commercial solutions. But none of them struck the balance of flexibility, automation, and transparency quite like Traefik.
What began as a small side project for container routing has evolved into the backbone of my self-hosted infrastructure.
Why I Started Looking Beyond Nginx
For years, Nginx was my default choice. It’s powerful, rock-solid, and efficient. But it’s also manual — every new subdomain, every service behind Docker, every TLS certificate renewal required a small ritual of edits, reloads, and checks.
As my home-lab grew — with dozens of containers running on various hosts — the static approach began to show cracks:
- Managing configs for dynamic Docker stacks was cumbersome.
- Keeping Let’s Encrypt certificates organized across services became tedious.
- Scaling or redeploying containers meant touching the proxy each time.
I wanted something that would see my Docker environment and just work. That’s where Traefik entered the scene.
Enter Traefik
Traefik (pronounced traffic) is a modern reverse proxy and load balancer built with containers and microservices in mind.
What sets it apart is its dynamic configuration model — it doesn’t rely on static config files as much as on providers. Docker, Kubernetes, Consul, Nomad, file providers — Traefik listens to them, detects services, and routes traffic automatically.
I still remember the first time I added a simple Docker label to a container:
labels:
- "traefik.enable=true"
- "traefik.http.routers.blog.rule=Host(`blog.hmlab.cloud`)"
- "traefik.http.services.blog.loadbalancer.server.port=8080"
…and suddenly, the container was live on HTTPS, with a valid certificate and automatic redirects.
No manual config, no reloads. It just appeared.
What Makes Traefik Special
🔁 Dynamic Service Discovery
Traefik continuously monitors your Docker socket (or other providers) and updates routing rules in real time.
Spin up a new container — Traefik detects it instantly. Stop one — routes vanish automatically.
For self-hosters and small teams, this level of automation is gold.
🔐 Automatic HTTPS
Traefik integrates seamlessly with Let’s Encrypt.
Wildcard certificates, on-the-fly issuance, and renewal — all handled behind the scenes.
It even supports DNS-based challenges for internal domains like *.intranet.local, which is something Nginx never made truly elegant.
🧩 Middleware Power
Traefik’s middlewares are modular building blocks that let you shape traffic:
- Redirect HTTP → HTTPS
- Add headers (HSTS, CSP, custom security policies)
- Handle rate limiting
- Apply authentication
- Rewrite paths
These can be chained, combined, and reused. It’s almost like Lego for HTTP routing.
📈 Dashboard and Metrics
The built-in dashboard is not just pretty — it’s useful.
You can visualize all routers, services, and entrypoints, monitor certificate status, and see live connections.
And if you’re running Prometheus, Traefik exports all metrics neatly for observability.
How I Use It in My Setup
In my home-lab cluster, Traefik sits at the edge — a single front door to dozens of internal services:
- WordPress and Nextcloud instances
- Fulcrum backend APIs
- Mailcow web UI
- Internal dashboards and monitoring tools
It runs as a Docker container, connected to an external proxy network shared with other stacks. Each application simply defines its routing through Docker labels — no centralized edits needed.
Here’s a snippet from my setup:
services:
traefik:
image: traefik:v3.1
command:
- "--providers.docker"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=admin@hmlab.cloud"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- proxy
It’s simple, declarative, and most importantly — self-maintaining.
When Traefik Might Not Be the Best Fit
As much as I admire Traefik, it’s not perfect.
- Learning curve: The dynamic, label-driven approach can feel alien to those used to traditional config files.
- Debugging: Because everything happens automatically, tracing why a route doesn’t work can require patience.
- Performance tuning: For ultra-high-throughput edge scenarios, Nginx or HAProxy may still be faster out of the box.
But for modern, containerized environments — especially those managed by a single person or small team — Traefik hits the sweet spot between automation and control.
Final Thoughts
For me, Traefik represents the next step in infrastructure evolution:
moving from static configuration toward self-aware, event-driven orchestration.
It’s elegant, reliable, and once you’ve experienced your containers auto-routing themselves, there’s no going back.
If you’re building your own homelab, running Docker Swarm or Kubernetes, or simply want to stop babysitting Nginx configs — give Traefik a try.
You might just find it becomes your favorite quiet workhorse too.
Written from the command line of hmlab.cloud — where Traefik quietly routes it all.