April 14, 2026 Infrastructure Caddy Self-hosting

Self-Hosting Infrastructure with Caddy

I have been self-hosting my personal infrastructure — this blog, a few side projects, and some internal tools — for about five years. For the first three, Nginx was the reverse proxy. It worked, but it was never pleasant. The configuration syntax is powerful and opaque. Every time I needed a new subdomain I copied a block from Stack Overflow and hoped. Let's Encrypt integration required certbot, a cron job, and occasional manual intervention when rate limits were hit.

Last year I switched to Caddy. It is written in Go, which was the initial attraction — I can read the source if something breaks. But the real reason I stayed is the configuration model. Caddy uses a JSON-native config with a Caddyfile frontend that is actually readable. The entire HTTPS setup for this site is two lines:

korvanti.com {
    tls admin@korvanti.com
    file_server
}

That is it. Automatic HTTPS via ACME. HTTP/2 and HTTP/3 enabled by default. No certbot. No cron jobs. No manual certificate management. When I added a new subdomain last month, Caddy obtained the certificate before I had finished testing the DNS propagation.

The middleware model is also cleaner than Nginx's location blocks. I use a custom Caddy module for some internal routing logic — written in Go, compiled into the binary with xcaddy. The module is about 400 lines and handles authentication for a private API. In Nginx this would have required Lua or a separate auth service. In Caddy it is just another handler in the chain.

"Good infrastructure is infrastructure you forget exists. Caddy gets closer to that ideal than anything else I have used."

I run Caddy on a small VPS in Stockholm. The binary is statically linked, so deployment is a single file transfer and a systemd reload. Memory usage is around 30MB at steady state, which is negligible on a 2GB instance. I have not had a production incident related to the proxy since the switch.

The only downside I have found is that the Caddyfile syntax is less well-documented than Nginx's for advanced use cases. When I needed to set up a complex rewrite with capture groups, I ended up reading the Caddy source code to understand the matcher semantics. But the source is clean and well-commented, so this was not a frustrating experience — just a different one.

If you are still managing certificates manually or fighting Nginx config syntax, I would recommend trying Caddy for a small project. The time you save on TLS alone is worth the migration effort.