(Editor’s note: This post has been updated since publication.)
Let’s Encrypt has steadily improved since its public debut in late 2015. Certbot, the most popular Let’s Encrypt client, is available for a wide variety of Linux distributions, making it easy to integrate Let’s Encrypt with many common web server configurations. However, because of this broad support, and because Certbot offers many internal options, there are several different ways to integrate Certbot with Nginx.
If you run Certbot with the
--nginx flag, it will automatically make whatever changes are necessary to your Nginx configuration to enable SSL/TLS for your website. On the other hand, if you’d prefer to handle the Nginx configuration separately, you can run Certbot with the
--webroot flag. In this mode, Certbot will still fetch a certificate, but it’s up to you to integrate it with Nginx.
Once you’ve obtained certificates from Let’s Encrypt, you’ll need to set up a method to automatically renew them, since they expire after just 90 days. On Ubuntu 18.04, the “certbot” package from the Ubuntu repositories includes an automatic renewal framework right out of the box. However, you’ll also need to reload your web server so it can actually serve the renewed certificates. The packaged renewal scripts on Ubuntu won’t restart Nginx unless you used the
--nginx flag to request certificates in the first place. If you’re using
--webroot or some other method, there’s an additional important step to take.
Automatically Restarting Nginx
On Ubuntu 18.04, Certbot comes with two automated methods for renewing certificates: a cron job, located at
/etc/cron.d/certbot, and a systemd timer. The cron job is set to run every 12 hours but only takes effect if systemd is not active. Instead, the systemd timer (visible in the output of
systemctl list-timers) works in tandem with the
certbot systemd service to handle certificate renewals.
Instead of modifying the cron job or the systemd service, we can change Certbot’s renewal behavior by editing a config file. Add the following line to
deploy-hook = systemctl reload nginx
This will cause Certbot to reload Nginx after it renews a certificate. With the
deploy-hook option, Certbot will only reload Nginx when a certificate is actually renewed, not every time the Certbot renewal check runs. Ed: A previous version of this post recommended using
renew-hook instead. This option has been superseded by
You can verify that your changes are working by running
certbot renew --dry-run. This will not renew any certificates but will tell you if your
deploy-hook command is being picked up by Certbot.
A Little Background Information
If you’re new to Let’s Encrypt, and you’re wondering why you need to automatically renew your certificates and restart your web server when you get new ones, it’s a good thing you’re here. While “traditional” SSL/TLS certificates are manually requested and can be valid for up to two years, certificates from Let’s Encrypt are only valid for 90 days. In their blog post, the Let’s Encrypt team explains their reasoning behind such short certificate lifetimes: they limit the time period for damage to be caused by stolen keys or mis-issued certificates, and they heavily encourage automation, which is key to the success of the Let’s Encrypt model.
This means that you’re going to need to automatically renew your certificates in order to take full advantage of Let’s Encrypt. Fortunately, since this is how Let’s Encrypt is designed to work, auto-renewal functionality is built directly into Certbot, the recommended ACME client for Let’s Encrypt.
A slightly less obvious question is why you’d want to automatically restart your web server as well. The answer is simple: web servers, such as Apache or Nginx, don’t read your SSL/TLS certificates directly from disk every time they need them. Instead, they load them into memory along with the rest of the web server configuration. This is great, and perfectly normal, since reading the certificates from disk would be horribly inefficient. However, it means that updating (or renewing) a certificate with Let’s Encrypt won’t directly change the certificate that Apache/Nginx serves when a page is requested. Instead, the web server must be restarted in order to load the new certificate into memory.