Almost every service on your server ends up behind a reverse proxy sooner or later: it accepts requests on port 80/443, handles HTTPS, and routes traffic to the right container. But which one should you use? Nginx is the classic, Caddy is the simplest, Traefik is the Docker specialist. In this part of the "Production-Ready Server" series, we compare all three using the same example — so you can make a decision that fits your setup, not just the loudest recommendation online.
20 minBeginnerTested on Ubuntu 24.04, DockerUpdated 2026-07-07
In short
For most VPS setups with a handful of services, Caddy is the best choice: automatic HTTPS, minimal configuration. Traefik pays off when containers are constantly being added and removed. Nginx remains the right call if you need maximum control, run unusual configurations, or it's simply already running.
Before we compare, a quick look at the shared foundation. A reverse proxy handles four jobs on your server: it's the only service listening on ports 80 and 443, it terminates TLS (i.e., HTTPS including certificates), it routes requests to the right internal service based on domain, and it shields your containers from direct internet access. Your services themselves only bind to 127.0.0.1 or stay entirely within the Docker network, exactly what we did in Part 1 with Grafana.
To keep the comparison fair, all three candidates solve the same task: serving Grafana at grafana.your-domain.com over HTTPS, with automatic redirection from HTTP.
Nginx powers a significant chunk of the internet, is extremely performant, and can do almost anything: reverse proxying, load balancing, caching, rate limiting, static file serving. The price for that is manual work, and above all when it comes to certificates, which you manage separately with Certbot.
On top of that comes the certificate, which Certbot issues and renews automatically:
Strengths: unbeatable flexibility, a huge community, a documented solution exists for almost any problem. Very light on RAM and CPU. The de facto standard every admin knows.
Weaknesses: the configuration is verbose, so you need to know the proxy_set_header lines above, otherwise WebSockets (which Grafana uses) won't work. HTTPS is a separate system with its own failure points. Every change means: edit the file, nginx -t, reload.
That's not a shortened example. Caddy fetches the certificate from Let's Encrypt itself, renews it automatically, redirects HTTP to HTTPS, sets the right proxy headers, and supports WebSockets with no extra configuration. Our Caddy tutorial shows how to set it up.
Strengths: automatic HTTPS as a core feature, not an add-on. The configuration is so short there's barely room for mistakes. Sensible, secure defaults (modern TLS versions, HTTP/2 and HTTP/3 out of the box). Every additional service just adds three lines.
Weaknesses: for very specific requirements, such as complex caching or unusual rewrite logic, the documentation gets thinner and the community smaller than Nginx's. If you want to reuse ready-made configs from the internet, you'll almost always find Nginx examples and have to translate them.
Traefik flips the principle around: instead of a central configuration file, it reads the Docker socket and configures itself based on labels on your containers. The proxy itself is set up once:
Everything else then happens directly on the respective service. Grafana just gets labels in the compose file:
Start the container, and the route exists. Stop it, and the route disappears. No reload, no touching a central file.
Strengths: perfect when services come and go dynamically, the routing configuration lives with the service itself, not in a central file. Automatic HTTPS just like Caddy. Built-in dashboard shows all routes and their status.
Weaknesses: the steepest learning curve of the three -> routers, services, middlewares, entrypoints, and resolvers are distinct concepts you have to internalize first. For services outside of Docker (say, a local application running directly on the host), configuration is more cumbersome than with the other two. And typos in labels fail silently: the container starts normally, only the route is missing.
Docker socket = root access
Traefik (and any other tool with access to /var/run/docker.sock) effectively has root privileges on the host as a result. Mount the socket read-only as shown in the example, and for exposed setups consider a socket proxy that restricts the API to read-only access.
A word of honesty about performance: on a typical VPS with a handful of services, it's not a deciding factor. All three handle far more traffic than the applications behind them can process. Benchmarks where Nginx comes out a few percent ahead concern load levels you'll never reach on a single server — decide based on maintainability, not synthetic numbers.
Choose Caddy if you're running a VPS with a manageable number of services and just want HTTPS to work — no certificate cron jobs, no studying headers. That covers most self-hosting setups, which is why our tutorials also use Caddy as the default.
Choose Traefik if your setup is alive: lots of containers, frequent deployments, maybe several projects on one host. As soon as the thought "new service = touch the central proxy config" makes you wince, you're a Traefik candidate.
Choose (or keep) Nginx if you genuinely need its flexibility, such as fine-grained caching, complex rewrites, or rate limiting, or if you already have a mature Nginx setup that runs reliably. A working reverse proxy is not a reason to migrate.
And if you do want to switch: the transition is forgiving, because the services behind it don't notice anything. Set up the new proxy in parallel on different ports, move a non-critical subdomain over as a test, then follow up domain by domain. The only thing you don't carry over are the Let's Encrypt certificates — instead, the new proxy simply gets its own.
There's no "best" reverse proxy, but there is the right one for your setup: Caddy for uncomplicated self-hosting, Traefik for dynamic container landscapes, Nginx for special cases and existing systems. More important than the choice is making sure everything behind it is set up cleanly — your services not publicly bound, the firewall configured, and monitoring from Part 1 keeping watch.
In the next part of our "Production-Ready Server" series, we'll set up uptime monitoring with Uptime Kuma. That way you'll get warned even when your service is unreachable from the outside, despite everything looking green on the server itself.
Permanently, that's rarely a good idea, but for a migration it works well: the new proxy initially listens on different ports (e.g. 8080/8443), you test a subdomain, and only at the end do you swap over ports 80/443. Only one process can bind to a port.
Do I lose my certificates when switching?
Practically no: Caddy and Traefik automatically fetch new certificates from Let's Encrypt on first start, which takes seconds. Manually exporting old Certbot certificates isn't necessary.
Which proxy is the fastest?
In synthetic benchmarks, usually Nginx — but on a typical VPS running normal web applications, the difference is irrelevant, since the application behind it is the bottleneck. Decide based on maintainability and team knowledge, not benchmark bars.
Apache can serve as a reverse proxy, but plays to its strengths more as a classic web server. HAProxy is an excellent load balancer for large setups, but doesn't come with automatic HTTPS. For the typical VPS use case, the three candidates compared here are the more practical choice.