Why Automate Your Let's Encrypt SSL Certificate Renewal
A Let's Encrypt SSL certificate expires every 90 days. If you manage multiple sites on a VPS or dedicated server, manual renewal is a ticking time bomb: one missed renewal and your visitors see NET::ERR_CERT_DATE_INVALID. Google penalizes your SEO, and your clients lose trust instantly.
At Otomy, we manage infrastructure for dozens of SMBs across France and Algeria. Here's the exact method we deploy to automate SSL renewal on every server.
Prerequisites
Before you start, make sure you have:
- A Linux server (Ubuntu 22.04 / Debian 12 recommended)
- Certbot installed (the official Let's Encrypt client)
- A web server: Nginx or Apache
- Root or sudo access
- A domain name pointing to your server
Step 1 — Install Certbot the Right Way
Forget outdated PPAs. Use the official snap package to always have the latest version:
sudo apt update
sudo apt install snapd -y
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Verify the installation:
certbot --version
Step 2 — Obtain Your First Let's Encrypt SSL Certificate
With Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
With Apache
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Certbot automatically modifies your configuration to enable HTTPS and redirects HTTP traffic.
Step 3 — Automate Renewal with a Cron Job
Certbot installs a systemd timer or cron job by default. Check it:
systemctl list-timers | grep certbot
If the timer exists, you're covered. Otherwise, create a manual cron entry:
sudo crontab -e
Add this line:
0 3 */10 * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Breakdown:
0 3 */10 * *: runs every 10 days at 3 AM--quiet: suppresses output unless there's an error--deploy-hook: reloads Nginx only if the certificate was actually renewed
For Apache, replace with systemctl reload apache2.
Step 4 — Test Renewal with a Dry Run
Never trust an untested configuration:
sudo certbot renew --dry-run
If you see Congratulations, all simulated renewals succeeded, you're all set.
Step 5 — Set Up Failure Alerts
Automation without monitoring is negligence. Here are three approaches we use at Otomy:
Option A — Email Alert via Cron
0 3 */10 * * certbot renew --quiet --deploy-hook "systemctl reload nginx" || echo "SSL renewal FAILED" | mail -s "[ALERT] SSL" admin@yourdomain.com
Option B — Webhook to n8n or Make
If you use n8n (which we deploy for our clients), create a workflow that receives a webhook on failure:
0 3 */10 * * certbot renew --quiet --deploy-hook "systemctl reload nginx" || curl -X POST https://your-n8n-instance.com/webhook/ssl-fail -d '{"server":"prod-01"}'
n8n can then send a Slack notification, an email, or create a ticket in your project management tool.
Option C — External Monitoring
Use UptimeRobot or Better Uptime to monitor your certificate's expiration date. Set an alert for 14 days before expiry.
Advanced: Wildcard SSL with DNS Challenge
For a wildcard certificate (*.yourdomain.com), the HTTP challenge isn't enough. You need a DNS challenge:
sudo certbot certonly --manual --preferred-challenges dns -d "*.yourdomain.com" -d yourdomain.com
To automate the DNS challenge, use a Certbot plugin for your DNS provider:
- Cloudflare:
sudo snap install certbot-dns-cloudflare - OVH:
pip install certbot-dns-ovh - DigitalOcean:
sudo snap install certbot-dns-digitalocean
Example with Cloudflare:
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/cloudflare.ini -d "*.yourdomain.com" -d yourdomain.com
File /root/.secrets/cloudflare.ini:
dns_cloudflare_api_token = YOUR_API_TOKEN
Secure this file:
chmod 600 /root/.secrets/cloudflare.ini
DevSecOps Best Practices
- Never store private keys in a Git repository
- Centralize certificate management across multiple servers — a tool like Ansible can run
certbot renewacross your entire fleet - Verify the certificate chain with
openssl:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null 2>/dev/null | openssl x509 -noout -dates
- Enable HSTS in your Nginx configuration to enforce HTTPS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Summary Checklist
| Step | Command / Action |
|---|---|
| Install Certbot | snap install --classic certbot |
| Obtain certificate | certbot --nginx -d domain.com |
| Automate renewal | Cron job or systemd timer |
| Test | certbot renew --dry-run |
| Alert on failure | Email, n8n webhook, UptimeRobot |
| Wildcard | Cloudflare/OVH DNS plugin |
Conclusion
Automating your Let's Encrypt SSL certificate renewal isn't a luxury — it's a requirement for any serious infrastructure. In 30 minutes, you eliminate a major downtime risk and strengthen your security posture.
Need help securing your infrastructure? Otomy supports SMBs in France and Algeria with server configuration, DevSecOps, and automation. Get in touch.