Setup Let’s Encrypt certificate with Nginx, Certbot and Docker

(λx.x)eranga
Effectz.AI
Published in
4 min readNov 14, 2020

--

Background

Let’s Encrypt is certificate Authority (CA) which provides free SSL certificates. By default these certificates expires in 90 days. We can renew the certificates before expiring and continue to using them to have HTTPS services. There is a Certbot client which can used to automate the certificate obtain and renewals. In this post I’m gonna discuss about automating Let’s Encrypt certificate obtain and renewal with Nginx and Docker by using the Certbot tool. All the source codes which related to this post available in gitlab. Please clone the repo and continue the post.

Scenario

I have a domain named climguards.com. The services which related to this domain have configured in DigitalOcean droplet. I’m gonna obtain a certificate for this domain from Let’s Encrypt. Following are the steps I have followed to obtain and configure the Let’s Encrypt certificates in the DigitalOcean droplet which related with climguards.com domain.

Dockerize Nginx with Certbot

First I have Dockerized Nginx with Certbot. Following is the Dockerfile I have used. I have run Nginx and Certbot in single Docker container. If want we can run them on separate Docker containers as well.

When issuing the certificates for a domain, Let’s Encrypt verifies the domain name and ownership via ACME challenge. To have this I need to update Nginx configuration with a server node listening to port 80 and serving the .well-known folder where the acme-challenge file will be dropped. Following is the Nginx configuration file I have created with this configurations.

I have built the Nginx Docker image with this configuration file and pushed to docker hub. To obtain certificates I run the Nginx docker in DigitalOcean droplet. Following is the docker-compose.yml file I have used to run the Nginx. Nginx container can be started with docker-compose up -d nginx command. In the docker-compose I have defined the Docker volume for the /etc/letsencrypt directory where stores the Let’s Encrypt certificate files. Before run the Nginx please make sure port 80 and port 443 are open in the firewall.

Obtain Certificate

The Certbot command resides inside the Nginx docker container. To obtain certificate I have connected to Nginx docker container and issued following Certbot command. Before do that, you need to be aware that Let’s Encrypt has rate limits. Most notably, there’s a limit of 20 issued certificates per 7 days. So if you exceeded 20 requests and are having a problem with generating your certificate for whatever reason, you could run into trouble. Therefore, it’s always wise to run your commands with a --staging parameter which will allow you to test if your commands will execute properly before running the actual commands. If everything runs well the certificate will be downloaded into /etc/letsencrypt/live/climguards.com/ directory inside the Nginx docker container. Since I have a Docker volume for /etc/letsencrypt/ directory, the certificates will be available in host machine as well.

If the staging command executed successfully, I can execute the command to get a live certificate. In this command I have replaced the --staging flag with the --force-renewal flag, which will tell Certbot that I want to request a new certificate with the same domains as an existing certificate.

In here I have manually enter the Certbot command inside Nginx docker container to obtain the Let’s Encrypt certificates. Instead of obtaining the certificates by manually entering the Certbot commands we can automate them via a shell script as well. In a coming post I will discuss about it. For now you can find more details from this blog post.

Nginx with SSL

Now I can enable the SSL in Nginx with using the Let’s Encrypt certificates. Following is the climguards.com Nginx config file with SSL configurations. It contains server entries for both HTTP and HTTPS. The other thing to notice is I have defined a proxy_pass reverse proxy entry to serve an internal API via Nginx. Read more about reverse proxy configuration of Nginx from this post.

Following is the new Dockerfile to dockerize the SSL enabled Nginx. It adds the SSL certificates in the /etc/letsencrypt/live/climguards.com/ directory into Nginx Docker image. These certificates used in the climguards.com Nginx config file. I can built and run the new Nginx Docker with same docker-compose.yml which mentioned above.

Renew Certificates

As mentioned about the Let’s Encrypt certificates will expires after 90 days. We can renew the certificates before expiring by using the certbot renew --dry-run command. Certbot renew command can be run with --dry-run option to test the script before using in the production. To automate the certificate renewal I have added this Certbot renew command into Crontab inside the Nginx docker. This Crontab command will run every night at 23:00. If the certificates are due for renewal, the certificates will renew. Following is the docker-entrypoint.sh which I have used to add Certbot renew command into Crontab while starting the Nginx.

Reference

  1. https://delattreconsulting.com/2020/02/lets-encrypt-ssl-certificate-through-certbot-for-nginx-in-a-docker-environment/
  2. https://www.digitalocean.com/community/tutorials/how-to-secure-a-containerized-node-js-application-with-nginx-let-s-encrypt-and-docker-compose
  3. https://www.humankode.com/ssl/how-to-set-up-free-ssl-certificates-from-lets-encrypt-using-docker-and-nginx
  4. https://geko.cloud/nginx-and-ssl-with-certbot-in-docker-alpine/
  5. https://www.cloudbooklet.com/how-to-install-nginx-and-lets-encrypt-with-docker-ubuntu-20-04/
  6. https://ilhicas.com/2019/03/02/Nginx-Letsencrypt-Docker.html

--

--