needy-wire.dev

Moving certbot from standalone to webroot

Standalone mode spins up its own web server on port 80. That works until nginx (or anything else) needs that port, and then renewals start failing silently at 3 a.m.

The fix is to serve /.well-known/acme-challenge/ from a directory and point certbot at it:

location ^~ /.well-known/acme-challenge/ {
    root /var/www/letsencrypt;
    default_type text/plain;
}

Then set authenticator = webroot in the renewal config, add a deploy hook that reloads nginx, and verify with certbot renew --dry-run. Done.