Why I switched from Nginx to Caddy
I ran Nginx as my reverse proxy for about a year. It worked fine, but every time I added a new service, the same ritual played out: write a server block, configure SSL with Certbot, set proxy headers, test the config, reload Nginx. Repeat.
Caddy does all of that in two lines and handles HTTPS automatically. The switch took about 20 minutes and I have not missed Nginx once.
What Nginx required
A typical Nginx reverse proxy config for one service looked like this:
server {
listen 80;
server_name nextcloud.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name nextcloud.example.com;
ssl_certificate /etc/letsencrypt/live/nextcloud.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nextcloud.example.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Plus Certbot setup, cron jobs for renewal, and the occasional renewal failure that left a service without HTTPS until I noticed.
Multiply that by 8 services and you have a lot of configuration to maintain.
What Caddy requires
The equivalent Caddy config:
nextcloud.example.com {
reverse_proxy localhost:8080
}
That is it. Caddy handles:
- Obtaining the TLS certificate from Let's Encrypt
- Automatic renewal before expiration
- HTTP to HTTPS redirect
- Proper proxy headers
For 8 services, my entire Caddyfile is about 30 lines compared to over 200 lines of Nginx config.
The migration
I listed all my Nginx server blocks, wrote the equivalent Caddyfile entries, stopped Nginx, started Caddy, and everything worked. The whole process was about 20 minutes, most of which was copying service names and port numbers.
Caddy obtained fresh certificates for all domains on first start. No Certbot migration needed.
What I lost
Fine-grained caching control. Nginx has more detailed caching directives. For my use case (just proxying), this does not matter.
Community size. Nginx has decades of Stack Overflow answers and tutorials. Caddy's documentation is good, but you find fewer third-party guides. This gap is closing as Caddy's popularity grows.
Muscle memory. I knew Nginx config syntax by heart. Learning Caddyfile syntax took about an hour of reading the docs.
What I gained
Zero certificate management. No Certbot, no renewal scripts, no monitoring for expiration. Certificates just work.
Readable configuration. I can look at my Caddyfile and understand what every service does in seconds. Nginx configs required mental parsing.
Faster iteration. Adding a new service is two lines and a reload. I self-host more services now because the overhead of exposing them is nearly zero.
If you are happy with Nginx and have everything automated, there is no urgent reason to switch. But if you are starting fresh or tired of managing certificates manually, Caddy is the better choice.
Sources
Related posts
Automating workflows with n8n
How I use n8n as a self-hosted alternative to Zapier for connecting services and automating repetitive tasks.
Self-hosting with Docker Compose: lessons learned
Practical patterns and mistakes from running self-hosted services with Docker Compose.
How Docker image layers actually work under the hood
A deep dive into Docker image layers, union filesystems, content-addressable storage, copy-on-write, and why understanding this stuff makes you better at writing Dockerfiles.
Enjoying the blog? Subscribe via RSS to get new posts in your reader.
Subscribe via RSS