FYI, my nginx config has this block as a standalone file, which is include
d into each server.
location /.well-known/acme-challenge {
if (-f /etc/nginx/_flags/certbot-8181) {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8181;
break;
}
rewrite ^.*$ @acme_503 last;
}
location = @acme_503 {
internal;
return 503;
}
and my certbot command is:
./certbot-auto renew --standalone --preferred-challenge=http-01 --http-01-port=8181 --force-renewal --pre-hook "touch /etc/nginx/_flags/certbot-8181" --post-hook "rm /etc/nginx/_flags/certbot-8181"
/etc/nginx/_flags/certbot-8181
is used as a filesystem semaphore. if it exists, traffic is proxied up into the certbot port; if it doesn’t exist, we redirect to a 503 error. this is an old nginx performance trick i learned a long time ago for toggling downtime or other config situations - in practice even under high load, most of these FS checks should happen within memory by the os, and never touch the disk.
you still need to restart nginx if there is a new cert, but we do that daily as part of app deployments.