Certbot and nginx - renewal and setup without service downtime

When installing/renewing let’s encrypt on a web server with nginx, we have to decide whether to do it with a temporary server, which means we must temporarily stop the web service, or indicate what the DocumentRoot of the web server is for the domain.

The latter implies that the website or service has a “public” DocumentRoot, and that’s not always easy when we’re using, for example, a Python, Java, or Go application and nginx as a proxy.

To be able to create or renew the certificate without stopping the service, we can create an “alias” in nginx for the domain that points to a temporary folder.

If we create the folder /tmp/letsencrypt-auto

In the domain configuration in nginx we’ll add inside server { }:

[...]

  location /.well-known/acme-challenge {
    default_type "text/plain";
    root        /tmp/letsencrypt-auto;
  }

[...]

With a reload of nginx (without service downtime) we’ll have this configured.

With this, any request to domain/.well-known/acme-challenge will be answered by the content of our /tmp/letsencrypt-auto folder

So we’ll generate it with

certbot certonly --webroot -w /tmp/letsencrypt-auto -d mydomain.com

From this moment on, we can automate the certificate renewal by putting in the crontab a

certbot renew

NOTE: It’s also important to put a task in the crontab to reload the nginx, because otherwise, even if we have the renewed certificate, nginx won’t be using the updated certificate but the previous one.