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 renewalpost/— 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.