Category: Automation

How to Renew SSL Certificates with Certbot in Docker (Works with Azure or AWS Domains)

If you’re running Nginx in a Docker container (for example, on a Raspberry Pi or a self-hosted server), and your domains are managed through Azure DNS or AWS Route 53, this step-by-step guide will show you how to automatically renew Let’s Encrypt SSL certificates using Certbot with the webroot method.

1. Prerequisites

Before getting started, make sure you have:

  • Docker and docker-compose installed
  • Certbot installed on the host system (not inside the container)
  • Nginx running inside a Docker container
  • Access to your DNS zone (Azure or AWS)
  • A domain pointing to your public IP (check with https://whatismyip.com)

2. Your docker-compose.yml Setup

Here’s a sample docker-compose.yml configuration for Nginx:

version: '3'
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - /usr/share/nginx/html:/usr/share/nginx/html
      - /etc/letsencrypt:/etc/letsencrypt:ro
    ports:
      - "80:80"
      - "443:443"
    networks:
      - default
      - yourproject_wp_net

networks:
  yourproject_wp_net:
    external: true

3. First-time Certificate Issuance with Certbot (using webroot)

Use the webroot method to avoid stopping Nginx and prevent port conflicts:

sudo certbot certonly --webroot \
  -w /usr/share/nginx/html \
  -d yourdomain.com -d www.yourdomain.com \
  --cert-name yourdomain.com

4. Reloading Nginx When Certificates Are Renewed

Create this script at:

/etc/letsencrypt/renewal-hooks/deploy/reload_nginx_docker.sh

With the following contents:

#!/bin/bash
# Script to reload Nginx inside Docker

echo "Reloading Nginx container..."
docker-compose -f /path/to/your/docker-compose.yml exec nginx nginx -s reload || \
docker-compose -f /path/to/your/docker-compose.yml restart nginx

Make it executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload_nginx_docker.sh

5. Automate Renewals with Cron

Edit your system’s crontab:

sudo crontab -e

Add this line to run every midnight:

0 0 * * * certbot renew --webroot -w /usr/share/nginx/html

6. Verify That Everything Works

Run a dry run to simulate the renewal process:

sudo certbot renew --dry-run

Also, test if the challenge path is being served:

curl http://yourdomain.com/.well-known/acme-challenge/test.txt

7. If Your Domain is Managed in AWS Route 53

If you use AWS Route 53 instead of Azure, you can use Certbot’s DNS plugin:

sudo certbot -a dns-route53 -d yourdomain.com -d www.yourdomain.com

⚠️ 8. Common Issues and Fixes

ErrorCauseSolution
bind: address already in useSystem Nginx running outside DockerStop it with sudo systemctl stop nginx
Some challenges have failedDomain doesn’t point to your IPDouble-check DNS records and IP
Unable to find a Route53 hosted zoneDomain not in AWSUse webroot method or DNS plugin for Azure

Conclusion

With this setup:

  • Your SSL certificates will renew automatically via certbot renew
  • Your Nginx container will reload itself without downtime
  • Works with Azure or AWS domains
  • You retain full control without relying on external Certbot containers

Did This Guide Help You?

Leave a comment or share your setup! Hopefully, this saved you hours of debugging like it did for me. 😉

Learn More