Docs / Automation & IaC / How to Automate SSL Certificate Renewal with Certbot

How to Automate SSL Certificate Renewal with Certbot

By Admin · Mar 2, 2026 · Updated Apr 23, 2026 · 24 views · 3 min read

How to Automate SSL Certificate Renewal with Certbot

Certbot is the most popular tool for obtaining and renewing free SSL/TLS certificates from Let's Encrypt. Automating certificate renewal on your Breeze instance ensures your sites never go down due to expired certificates.

Installing Certbot

Install Certbot using snap (recommended) on your Breeze instance:

# Remove any old OS-packaged certbot
sudo apt remove -y certbot

# Install via snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Verify
certbot --version

Obtaining Your First Certificate

Use the appropriate plugin for your web server:

# For Nginx
sudo certbot --nginx -d example.com -d www.example.com

# For Apache
sudo certbot --apache -d example.com -d www.example.com

# Standalone mode (stops web server temporarily)
sudo certbot certonly --standalone -d example.com

# Webroot mode (no downtime)
sudo certbot certonly --webroot -w /var/www/html -d example.com

Understanding the Renewal Process

Let's Encrypt certificates are valid for 90 days. Certbot installs a systemd timer or cron job that automatically attempts renewal twice daily:

# Check if the timer is active
sudo systemctl status certbot.timer

# View the timer schedule
sudo systemctl list-timers | grep certbot

# Test renewal without making changes
sudo certbot renew --dry-run

Custom Renewal Hooks

Run scripts before, during, or after renewal to reload services or notify your team:

# Create a deploy hook to reload Nginx after renewal
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy

cat <<'HOOK' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
echo "$(date): Nginx reloaded after cert renewal for $RENEWED_DOMAINS" >> /var/log/certbot-deploy.log
HOOK

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

The three hook directories are:

  • pre/ — runs before attempting renewal (e.g., stop a standalone service)
  • deploy/ — runs after a successful renewal
  • post/ — runs after every renewal attempt, regardless of outcome

Wildcard Certificates with DNS Validation

For wildcard certificates, use DNS-01 challenge with a DNS plugin:

# Install the Cloudflare DNS plugin
sudo snap install certbot-dns-cloudflare

# Create credentials file
sudo mkdir -p /etc/letsencrypt
cat <<EOF | sudo tee /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini

# Obtain a wildcard certificate
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d "*.example.com" \
  -d example.com

Monitoring Certificate Expiry

Add a simple monitoring script to alert you if renewal fails:

#!/bin/bash
# /usr/local/bin/check-certs.sh
for cert_dir in /etc/letsencrypt/live/*/; do
  domain=$(basename "$cert_dir")
  expiry=$(openssl x509 -enddate -noout -in "${cert_dir}fullchain.pem" | cut -d= -f2)
  expiry_epoch=$(date -d "$expiry" +%s)
  now_epoch=$(date +%s)
  days_left=$(( (expiry_epoch - now_epoch) / 86400 ))

  if [ "$days_left" -lt 14 ]; then
    echo "WARNING: $domain expires in $days_left days!" | \
      mail -s "SSL Certificate Expiry Warning" admin@example.com
  fi
done

Best Practices

  • Always test with --dry-run — verify renewal works before relying on automation
  • Monitor the certbot timer — ensure the systemd timer stays active and enabled
  • Use deploy hooks — reload web servers and proxies automatically after renewal
  • Set up expiry alerts — catch failures before certificates actually expire
  • Prefer DNS-01 for wildcards — avoids port 80 requirements and supports wildcard domains

With Certbot properly configured, your Breeze instances will maintain valid SSL certificates indefinitely with zero manual intervention.

Was this article helpful?