Skip to content

How to Set Up Automatic Certbot Certificate Renewal

DodaTech 2 min read

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-upgrade flag.
  • Test the renewal Process after every Certbot version upgrade.
  • Keep the post renewal hook simple to avoid silent failures.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro