A beginner's guide to automated SSL certificate renewal with Let's Encrypt and Certbot on Nginx using Docker

This blog provides a step-by-step guide on automating the SSL certificate renewal process using Let's Encrypt and Certbot on an Nginx web server within a Docker container. It explains the importance of SSL certificates for website security, introduces Let's Encrypt as a cost-effective solution, and emphasizes the need for automating certificate renewal due to Let's Encrypt's 90-day validity period.

GraphQL has a role beyond API Query Language- being the backbone of application Integration
background Coditation

A beginner's guide to automated SSL certificate renewal with Let's Encrypt and Certbot on Nginx using Docker

SSL certificates are an essential component of website security. They provide a secure connection between a website and its visitors, ensuring that sensitive information, such as login credentials and payment details, is encrypted and protected from cyber threats.

Let’s Encrypt as Solution:

Let’s Encrypt is a trusted SSL certificate authority provider that offers free trusted SSL certificates for one domain. By using Let's Encrypt, you can secure your website with a trusted SSL certificate without paying any fees. This makes it an excellent choice for small businesses and personal websites that want to provide a secure browsing experience for their visitors. Get started with Let's Encrypt today and enjoy the benefits of a secure website!

The Need for Automating SSL Certificate Renewal:

Automating the SSL certificate renewal process is crucial for maintaining the security and trustworthiness of your website. Let's Encrypt free SSL certificates expire every 90 days, which means you need to renew them regularly to ensure uninterrupted service. Manually renewing SSL certificates can be a time-consuming and error-prone process, especially if you have multiple domains or subdomains. That's why automating the SSL certificate renewal process is essential. By automating the process, you can ensure that your SSL certificates are always up-to-date and that your website remains Safe.

Self-signed SSL certificates

Self-signed SSL certificates are created by the domain owner to support HTTPS and SSL handshakes before establishing a connection between the client and server. However, these certificates are not verified by a trusted certificate authority, making them insecure. When visitors connect to a website with a self-signed certificate, their browser fails to verify the domain's identity, making it easier for attackers to perform man-in-the-middle attacks and intercept sensitive information. 

SSL trusted by Certificate Authority Provider

To verify the identity of a domain, web browsers rely on trusted third-party SSL certificate providers. By using a trusted certificate authority (CA), visitors to a website can ensure that their information transmitted over networks is encrypted and the connection is secure. This is why businesses and organizations opt for SSL certificates provided by trusted CAs. 

Type of SSL Certificate

There are 3 types of certificates that can be procured using the let’s encrypt.

  • Wild-Card Trusted SSL CA
    Wild-Card Trusted SSL CA covers all sub-domains of a domain with a single certificate
  • Multiple sub-domain Trusted SSL CA
    Multiple sub-domain Trusted SSL CA covers several specific sub-domains with a single certificate
  • Single sub-domain Trusted SSL CA
    Single sub-domain Trusted SSL CA covers only one specific sub-domain with a single certificate.

In this, article we will use the example of a single sub-domain trusted SSL CA provided for free by Let’s Encrypt SSL CA Provider. However, the third-party providers require verification that the person or entity who is requesting for trusted SSL certificate can actually authorized to manage and control the DNS.
There are various types of verification challenges such as email verification and DNS Record entry or SMS-based OTP verification though these types of processes require some level of human intervention. This is the reason for most business entities fail to automate this process. 
Let’s Encrypt also provides CLI and supports one more verification process named acme-challenge. ACME is a protocol used by the third party to ensure the DNS belongs to the person or the entity requesting the Trusted SSL CA. In the below example, we will understand how to procure the trusted SSL Certificate automatically.


docker-compose.yaml
Version: '3'

  nginx:
    image: nginx
    labels:
      environment: ${ENVIRONMENT}
    volumes:
      - ./configs/${NGINX_CONFIG}:/etc/nginx/nginx.conf:ro
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    restart: always
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

  certbot:
    image: certbot/certbot
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 89d & wait $${!}; done;'"

In the above, example we have created 2 services one for Nginx and Certbot. Both services share the same volumes as the certbot will procure the Trusted SSL certificate and re-news it once expires. Once, the SSL certificate is created the Nginx service will consume it.


nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    server {
        listen 80;
        listen [::]:80;
        server_name <DNS>;

        location ~ /.well-known/acme-challenge {
            allow all;
            root /var/www/certbot;
        }
    }
}

Note: To automate the whole process it relies upon the HTTP (80) Port. So, make sure that the inbound ports are exposed publicly.

In the above Nginx configuration, we have exposed an end-point that will be consumed by the third party to complete the acme-challenge

http://<DNS>/.well-known/acme-challenge/<acme-code>

By using the above end-points let’s encrypt ensures via the public and private key-based authentication.


Init-lets-encrypt.sh
#!/bin/bash

if ! [ -x "$(command -v docker-compose)" ]; then
  echo 'Error: docker-compose is not installed.' >&2
  exit 1
fi

domains=(<DNS>)
rsa_key_size=4096
data_path="./data/certbot"
email="<DNS-OWNER-EMAIL>" # Adding a valid address is strongly recommended
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits

if [ -d "$data_path" ]; then
  read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
  if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
    exit
  fi
fi


if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
  echo "### Downloading recommended TLS parameters ..."
  mkdir -p "$data_path/conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
  echo
fi

echo "### Creating dummy certificate for $domains ..."
path="/etc/letsencrypt/live/$domains"
mkdir -p "$data_path/conf/live/$domains"
docker-compose run --rm --entrypoint "\
  openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\
    -keyout '$path/privkey.pem' \
    -out '$path/fullchain.pem' \
    -subj '/CN=localhost'" certbot
echo


echo "### Starting nginx ..."
docker-compose up --force-recreate -d nginx
echo

echo "### Deleting dummy certificate for $domains ..."
docker-compose run --rm --entrypoint "\
  rm -Rf /etc/letsencrypt/live/$domains && \
  rm -Rf /etc/letsencrypt/archive/$domains && \
  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
echo


echo "### Requesting Let's Encrypt certificate for $domains ..."
#Join $domains to -d args
domain_args=""
for domain in "${domains[@]}"; do
  domain_args="$domain_args -d $domain"
done

# Select appropriate email arg
case "$email" in
  "") email_arg="--register-unsafely-without-email" ;;
  *) email_arg="--email $email" ;;
esac

# Enable staging mode if needed
if [ $staging != "0" ]; then staging_arg="--staging"; fi

docker-compose run --rm --entrypoint "\
  certbot certonly --webroot -w /var/www/certbot \
    $staging_arg \
    $email_arg \
    $domain_args \
    --rsa-key-size $rsa_key_size \
    --agree-tos \
    --force-renewal" certbot
echo

echo "### Reloading nginx ..."
docker-compose exec nginx nginx -s reload

Above, script will procure the SSL certificate trusted by third party CA Provider and the validity of the certificate will be 90 days. So, run the script on your machine to procure the certificate for the first time. But, what happens if after 90 days and certificate expires?
Well, we already have set up the entry-point command of the certbot container in docker-compose.yaml to run after 89 days. However, we will have to keep running the cert docker container. 
However, if you do not want to keep it running then let’s set up a cron job that will run the script for us at the interval of 89 days. Or you can set the interval according to your needs. For instance, a day before the SSL certificate expires. i.e. 89 days.


0 0 */89 0 0 docker run --rm -it --name certbot -v 
"/docker-volumes/data/letsencrypt:/data/letsencrypt" -v 
"/docker-volumes/etc/letsencrypt:/etc/letsencrypt" -v 
"/docker-volumes/var/lib/letsencrypt:/var/lib/letsencrypt" -v 
"/docker-volumes/var/log/letsencrypt:/var/log/letsencrypt" certbot/certbot renew --webroot -w 
/data/letsencrypt --quiet && docker kill --signal=HUP production-nginx-container

Conclusion

As a trusted SSL certificate authority provider, Let's Encrypt offers free SSL certificates for 90 days. By automating the SSL certificate procurement process, small business owners who require a single domain can save money while still ensuring their website is secure and encrypted with sensitive information.
No matter which web server you are using or the type of SSL certificate. Using the above process you can still automate the process of renewing trusted SSL certificate CA by let’s encrypt.!

Want to receive update about our upcoming podcast?

Thanks for joining our newsletter.
Oops! Something went wrong.

Latest Articles

Optimizing Databricks Spark jobs using dynamic partition pruning and AQE

Learn how to supercharge your Databricks Spark jobs using Dynamic Partition Pruning (DPP) and Adaptive Query Execution (AQE). This comprehensive guide walks through practical implementations, real-world scenarios, and best practices for optimizing large-scale data processing. Discover how to significantly reduce query execution time and resource usage through intelligent partition handling and runtime optimizations. Perfect for data engineers and architects looking to enhance their Spark job performance in Databricks environments.

time
8
 min read

Implementing custom serialization and deserialization in Apache Kafka for optimized event processing performance

Dive deep into implementing custom serialization and deserialization in Apache Kafka to optimize event processing performance. This comprehensive guide covers building efficient binary serializers, implementing buffer pooling for reduced garbage collection, managing schema versions, and integrating compression techniques. With practical code examples and performance metrics, learn how to achieve up to 65% higher producer throughput, 45% better consumer throughput, and 60% reduction in network bandwidth usage. Perfect for developers looking to enhance their Kafka implementations with advanced serialization strategies.

time
11
 min read

Designing multi-agent systems using LangGraph for collaborative problem-solving

Learn how to build sophisticated multi-agent systems using LangGraph for collaborative problem-solving. This comprehensive guide covers the implementation of a software development team of AI agents, including task breakdown, code implementation, and review processes. Discover practical patterns for state management, agent communication, error handling, and system monitoring. With real-world examples and code implementations, you'll understand how to orchestrate multiple AI agents to tackle complex problems effectively. Perfect for developers looking to create robust, production-grade multi-agent systems that can handle iterative development workflows and maintain reliable state management.

time
7
 min read