When I first built my homelab I reached for a heavier ingress stack — tunnels, an extra proxy layer. It worked, but every change meant reasoning about three moving parts. I ripped it out for plain Traefik, and everything got simpler.
Labels are the whole API
Exposing a container is just labels on it:
labels:
- traefik.enable=true
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- traefik.http.routers.myapp.entrypoints=websecure
- traefik.http.routers.myapp.tls.certresolver=le
- traefik.http.services.myapp.loadbalancer.server.port=3000
A hostname, a port, done. Traefik discovers it, routes it, and mints a Let's Encrypt cert automatically.
Less is more
No tunnel daemon to babysit, no second proxy to keep in sync — one reverse proxy, configured through the same compose files as the apps it serves. When something breaks, there's exactly one place to look.
The fancier stack had its reasons, but for a single box running a few dozen services, vanilla Traefik is the sweet spot.




