How to Set Up Automatic Certbot Certificate Renewal
In this tutorial, you'll learn about How to Set Up Automatic Certbot Certificate Renewal. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Let's Encrypt certificates expire every 90 days. If you forget to renew manually, your site becomes inaccessible. You need automatic renewal that runs without manual intervention.
Quick Fix
Step 1: Check if Certbot is installed
certbot --version
Expected:
certbot X.Y.Z
Step 2: Enable the built-in systemd timer
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Certbot installs a systemd timer that runs certbot renew twice per day. It only renews certificates within 30 days of expiry, so the load is negligible.
Step 3: Verify the timer status
sudo systemctl status certbot.timer
Expected:
● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting)
Trigger: Thu 2024-06-25 10:30:00 UTC; 12h left
Step 4: Check when the timer last ran
sudo systemctl list-timers --all | grep certbot
Expected:
Thu 2024-06-25 04:30:00 UTC 12h ago certbot.timer certbot.service
Step 5: Add a cron job as fallback
echo "0 3 * * * root certbot renew --quiet && systemctl reload nginx" | sudo tee /etc/cron.d/certbot
This runs renewal daily at 3 AM. The --quiet flag suppresses output unless an error occurs.
Step 6: Test the renewal Process
sudo certbot renew --dry-run
Expected:
DRY RUN: Simulating renewal of an existing certificate
** DRY RUN: Congratulations, all renewals succeeded.
Step 7: Set up a renewal hook for web server reload
sudo mkdir -p /etc/letsencrypt/renewal-hooks/post
sudo tee /etc/letsencrypt/renewal-hooks/post/reload.sh << 'EOF'
#!/bin/sh
systemctl reload nginx || true
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload.sh
This hook runs after every successful renewal, ensuring the new certificate is loaded without manual intervention.
Step 8: Monitor with a log file
sudo journalctl -u certbot.service --since "1 week ago"
Expected:
Jun 25 04:30:01 hostname certbot[1234]: Certificate not yet due for renewal
Jun 25 04:30:01 hostname certbot[1234]: No renewal failures.
Alternative Solutions
Use acme.sh instead of Certbot for more advanced renewal configurations and DNS challenge support.
Common Errors
Timer is active but renewal never runs: Check if the system clock is correct with timedatectl. An incorrect clock causes the timer to miss its scheduled time.
Renewal hook script fails silently: If the web server does not reload after renewal, check the hook script's stderr. Add logging: systemctl reload nginx || echo "Reload failed" >> /var/log/certbot-renew.log.
Certbot not installed in cron PATH: cron runs with a limited PATH. Use the full path to certbot in Cron Jobs: /usr/bin/certbot renew --quiet.
Duplicate renewal attempts: If both the systemd timer and cron job are active, renewal runs twice daily. Disable one: sudo systemctl disable certbot.timer if using cron.
Prevention
- Add monitoring for certificate expiry — Cloudflare, UptimeRobot, or a custom script.
- Set up email alerts for renewal failures via Certbot's
--no-self-upgradeflag. - Test the renewal Process after every Certbot version upgrade.
- Keep the
postrenewal hook simple to avoid silent failures.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro