If you run anything in Docker beyond a single container, you eventually need a reverse proxy in front of it. We spent the last month migrating three production stacks across Caddy 2.8, Traefik v3.1, and nginx Proxy Manager 2.11 to see where each one earns its keep — and where it bites you at 2am. Configuration philosophy: three very different bets Caddy bets on convention. A working HTTPS site with automatic Let's Encrypt is roughly four lines of Caddyfile: example.com { reverse_proxy localhost:3000 } Enter fullscreen mode Exit fullscreen mode That's it. ACME challenges, certificate renewal, HTTP→HTTPS redirect, sane HSTS defaults — all built in. The JSON API underneath is verbose, but you rarely touch it unless you're building config programmatically. Traefik bets on discovery.…