web / caddy
When I run a web service on a VM, I use Caddy as a reverse proxy to terminate TLS in front of the app.
Config
# /etc/caddy/Caddyfile
sockeye.example.com {
reverse_proxy 127.0.0.1:1994
}
Point DNS at the box and reload:
sudo cp Caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy
The app listens on localhost. Caddy renews a Let's Encrypt certificate.
Compared to a PaaS
A PaaS like Render provisions certificates and terminates HTTPS at a shared edge with DDoS protection. Caddy gives me the same certificates on a VM. I lose the edge and gain control and a flat cost.
Caddy vs nginx
Both are fast enough at my scale. Caddy renews certificates by default.
nginx needs certbot and a renewal timer. Caddy is a single Go binary,
like everything else I deploy.
Caddy vs an app server
Caddy runs in front of an application server:
client --HTTPS--> Caddy (:443, TLS) --HTTP--> app (127.0.0.1)
Caddy fronts any localhost listener: a Go binary, or an app server such as Puma for a Ruby app.
CAA records
If certificate issuance fails, check the domain's CAA records. They restrict which authorities can issue certificates. If the apex excludes Let's Encrypt, add a record for the subdomain:
sockeye CAA 0 issue "letsencrypt.org"
A subdomain inherits CAA records until a closer record exists. This record overrides the apex policy for that host.