How to create auto-updating SSL certificates using Certbot and Docker

What is Certbot

Certbot is an free and open-source tool which allows users to create SSL certificates for their website, signed by a trusted authority.

With a trusted SSL certificate, HTTP servers such as Apache and NGINX can serve secure HTTPS content. This provides a layer of encryption which prevents third parties from intercepting information between web-browser and server.

The problem with Certbot

Managing software infrastructure is cumbersome and error prone. Several tools exist to help alleviate these issues (Ansible, Chef, Puppet) although these tools do not abstract away infrastructure completely; differences between environments and operating systems will still cause inconsistencies (RHEL may bundle a particular set of libraries, while Ubuntu bundles another).

The steps for configuring Certbot vary between systems. How to create an agnostic deployment of Certbot with automatic certificate renewal that will function correctly on any system? Enter Docker.

What is Docker

Docker is a containerisation system. That means that it bundles dependencies for an application into a self-contained unit called a container. “If it runs in a container, it will run anywhere”. By bundling Certbot and NGINX into containers, with appropriate configuration, we ensure that we have a portable installation of the latest version of Certbot, regardless of the version available from the repositories of our chosen Linux distribution.

Setting up Certbot in Docker

Step 1: Generating SSL Certificates

mkdir -p ./data/certbot/{conf,www} && \
docker run --rm -it \
    -v `pwd`/data/certbot/conf:/etc/letsencrypt \
    -v `pwd`/data/certbot/www:/var/www/certbot \
    -p 80:80 certbot/certbot certonly

Step 2: Creating an NGINX Configuration

mkdir ./data/nginx && cat << EOF > ./data/nginx/app.conf
server {
     listen 80;
     server_name example.com;
     location /.well-known/acme-challenge/ {
         root /var/www/certbot;
     }
     location / {
         return 301 https://$host$request_uri;
     }    
 }
 server {
     listen 443 ssl;
     server_name example.com;
     location / {
         proxy_set_header Host $host;
         proxy_set_header X-Forwarded-Proto https;
         proxy_pass http://your_backend;
     }
     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
 }
EOF

This NGINX configuration serves your application over HTTPS using the recently generated SSL certificates. Replace “http://your_backend” with the address of the application and “example.com” with your chosen domain name.

Step 3: Creating docker-compose.yml

version: '2'
 services:
   nginx:
     image: nginx:1.15-alpine
     command: sh -c 'nginx -g "daemon off;"& while true; do sleep 1200; nginx -s reload; done'
     ports:
       - 80:80
       - 443:443
     restart: unless-stopped
     volumes:
       - ./data/nginx:/etc/nginx/conf.d
       - ./data/certbot/conf:/etc/letsencrypt
       - ./data/certbot/www:/var/www/certbot
   certbot:
     image: certbot/certbot
     entrypoint: sh -c 'while true; do certbot renew; sleep 1200; done'
     volumes:
       - ./data/certbot/conf:/etc/letsencrypt
       - ./data/certbot/www:/var/www/certbot
     restart: unless-stopped

After creating the docker-compose file, type docker-compose up in the terminal to start the nginx and certbot services.

Leave a Reply

Your email address will not be published. Required fields are marked *