Automate Certbot SSL Renewals with Nginx & Apache Cron
Secure your site with free Let’s Encrypt SSL/TLS certificates using Certbot on Nginx or Apache, with automated renewal and easy setup.
5 min read
Securing your site with HTTPS is now a baseline requirement, not an option. Let’s Encrypt provides free SSL/TLS certificates, and Certbot automates both issuance and renewal. This guide walks you through installing Certbot, obtaining your first certificate, and setting up a reliable renewal process that works on Nginx or Apache.
Prerequisites
VPS or dedicated server running a supported Linux distribution (Ubuntu/Debian or AlmaLinux/Rocky / RHEL).
Root or sudo access.
Domain name pointing to the server’s public IP (A or CNAME record).
Web server (Nginx or Apache) already serving the site you want to protect.
Skip the installation steps if your web server is already up and running.
Installing Certbot
Ubuntu / Debian (apt)
# Update package lists
sudo apt update
# Install Certbot and the web‑server plugins
sudo apt install certbot python3-certbot-nginx python3-certbot-apache
The first command refreshes the package cache. The second installs the core Certbot client and the Nginx and Apache plugins, which let Certbot modify server configuration automatically.
AlmaLinux / Rocky Linux / RHEL (dnf)
# Enable the EPEL repository that contains Certbot
sudo dnf install epel-release
# Install Certbot and the web‑server plugins
sudo dnf install certbot python3-certbot-nginx python3-certbot-apache
The epel-release package adds the Extra Packages for Enterprise Linux repository, which hosts Certbot.
Obtaining Your First Certificate
Choose the plugin that matches your web server. The command will both obtain the certificate and configure the server to use it.
Open https://example.com in a browser. The lock icon should appear, and clicking it will show the certificate is issued by Let’s Encrypt. From the command line you can inspect the certificate dates:
Let’s Encrypt certificates expire every 90 days. Certbot includes a built‑in renewal command. While many distributions install a systemd timer, a cron job gives explicit control and works on any system.
1. Create a Renewal Script
Save the following as /usr/local/sbin/certbot-renew.sh and make it executable:
#!/bin/bash
# Attempt to renew all certificates
/usr/bin/certbot renew --quiet --deploy-hook "/usr/local/sbin/certbot-deploy.sh"
Explanation:
certbot renew – renews certificates that are within 30 days of expiration.
--quiet – suppresses non‑essential output (useful for cron).
--deploy-hook – runs the specified script only if a certificate was actually renewed.
2. Deploy‑Hook Script
Save as /usr/local/sbin/certbot-deploy.sh and make it executable:
#!/bin/bash
# Reload web servers after a successful renewal
if pgrep -x "nginx" > /dev/null; then
systemctl reload nginx
fi
if pgrep -x "httpd" > /dev/null || pgrep -x "apache2" > /dev/null; then
systemctl reload apache2
fi
* * * – every day of the month, every month, every day of the week.
The command redirects both standard output and error to /var/log/certbot-renew.log.
4. Test the Setup
Run the script manually to verify:
sudo /usr/local/sbin/certbot-renew.sh
If no certificates are due, Certbot will report “No renewals were attempted”. To simulate a renewal without contacting Let’s Encrypt, use the dry‑run option:
sudo /usr/bin/certbot renew --dry-run
Monitoring and Troubleshooting
Keep an eye on renewal health by reviewing the log file:
sudo less /var/log/certbot-renew.log
Successful renewals contain the line “Congratulations! Your certificate and chain have been saved”.
Common Issues
Port 80 blocked: Let’s Encrypt uses HTTP‑01 challenges on TCP 80. Ensure your firewall (ufw, firewalld, iptables) allows inbound traffic on port 80.
Incorrect DNS: The domain must resolve to the server’s public IP during the challenge. Verify with dig @8.8.8.8 example.com.
Permissions: The renewal script runs as root via cron, so it can reload services and write logs.
Optional Email Alerts
To receive notifications when a renewal fails, append the following to the end of certbot-renew.sh:
if [ $? -ne 0 ]; then
echo "Certbot renewal failed on $(date)" | mail -s "Certbot Alert" you@example.com
fi
Replace you@example.com with your monitoring address. This step is optional.
Conclusion
By installing Certbot, obtaining a Let’s Encrypt certificate, and configuring a lightweight cron job with a deploy‑hook, you ensure that your Nginx or Apache server always serves a valid HTTPS certificate. The setup works on both Debian/Ubuntu and AlmaLinux/Rocky / RHEL families, requires no manual intervention after the initial configuration, and provides clear logs for ongoing verification. With these steps in place, your websites, apps, and APIs remain secure without the overhead of tracking expiration dates.