Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Using Certbot Docker Image

Prerequisites

This tutorial assumes you have installed Docker.

Table Of Contents

Single Domain - Web Challenge

This will show you how to use the Certbot Docker image to generate Lets Encrypt SSL certificates through a web based challenge whereby this serves up a webpage with a token LetsEncrypt will look for on your domain. If it is able to find the token, it proves that you have control of the domain and thus can be provided with SSL certificates for that domain.

Thus, this method requires that this action be taken on the server that the domain points to, and also requires ports 80 and 443 whilst it runs, so your website will likely be unavailable whilst this runs.

Run the command below on your server (after changing the DOMAIN variable)

LETSENCRYPT_VOLUME_DIR=$HOME/letsencrypt
DOMAIN="www.mydomain.com"

sudo docker run \
  --interactive \
  --tty \
  --rm \
  --name certbot \
  -p 80:80 \
  -p 443:443 \
  -v "$LETSENCRYPT_VOLUME_DIR:/etc/letsencrypt" \
  certbot/certbot \
  certonly -d $DOMAIN --standalone

We need the --interactive and --tty in order to be able to answer questions the first time this runs.

After you have completed this once, you can automatically renew by running the following:

LETSENCRYPT_VOLUME_DIR=$HOME/letsencrypt
DOMAIN="www.mydomain.com"
EMAIL="support@mydomain.com"

sudo docker run \
  --rm \
  --name certbot \
  -p 80:80 \
  -p 443:443 \
  -v "$LETSENCRYPT_VOLUME_DIR:/etc/letsencrypt" \
  certbot/certbot \
  certonly --standalone -d $DOMAIN --quiet

This appears to only work with one domain at a time. Using multiple -d $DOMAIN with different domains won't work. I have removed the -it or --interactive and --tty because they should no longer be needed, and these won't work in an automation script from a cron service etc.

The certificates will be in $LETSENCRYPT_VOLUME_DIR/archive with a symlink to the latest ones in $LETSENCRYPT_VOLUME_DIR/live, so we can copy them to where we want by using:

sudo cp \
  --recursive \
  --dereference \
  $LETSENCRYPT_VOLUME_DIR/live \
  /path/to/output/dir

sudo chown --recursive $USER:$USER  /path/to/output/dir

Wildcard Certificate - DNS Challenge

If one uses a DNS provider, that has a supported Certbot DNS plugin, then you can easily generate wildcard certificates for your domain using the relevant plugin image. You can find the list of Certbot DNS Plugins on the Certbot Dockerhub page.

In this case, I am using DigitalOcean to manage my DNS records, and thus will be using the certbot/dns-digitalocean image. If you are using a different provider, swap out the image name, and update the credentials as required.

The following script will create a wildcard certificate for your domain, and place it in a folder named after your domain, on the same level of the script's location.

#!/bin/bash

# Specify your domain here (make sure there is no subdomain/wildcard)
DOMAIN="mydomain.com"

# Specify your email address for Lets encrypt to send you expiry reminders on
EMAIL="me@mydomain.com"

# Put your DigitalOcean token here.
DO_TOKEN="58xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9"

# Get the path to the directory ths script is in.
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

# Specify where to store the Lets Encrypt volume, where all of Certbot's state will be kept.
LETSENCRYPT_VOLUME_DIR=$DIR/letsencrypt

# Create our DigitalOcean credentials file for Certbot to use.
echo "dns_digitalocean_token = ${DO_TOKEN}" > $DIR/certbot-creds.ini
chmod 600 $DIR/certbot-creds.ini

sudo docker run \
  --rm \
  --name certbot \
  -v "$DIR/certbot-creds.ini:/certbot-creds.ini:ro" \
  -v "$LETSENCRYPT_VOLUME_DIR:/etc/letsencrypt" \
  certbot/dns-digitalocean \
  certonly \
  --dns-digitalocean \
  --email=$EMAIL \
  --agree-tos \
  --no-eff-email \
  --keep-until-expiring \
  --dns-digitalocean-credentials /certbot-creds.ini \
  -d "*.${DOMAIN}"

sudo cp --recursive --dereference $DIR/letsencrypt/live/$DOMAIN .
sudo chown $USER:$USER --recursive $DOMAIN

# cleanup
rm $DIR/certbot-creds.ini
  • ---dns-digitalocean tells certbot we want a DNS based challenge using DigitalOcean
  • --agree-tos - tells certbot that we agree to the terms of service.
  • --no-eff-email - tells certbot we do not want to be used for statistics.
  • --keep-until-expiring - tells certbot to do nothing if we were to run again before the certificate is even close to expiring.
  • --dns-digitalocean-credentials specifies the path to our credentials file (which needs to line up with the volume declaration).

The full list of command line options for Certbot can be viewed online

References

Last updated: 5th September 2022
First published: 12th March 2021