//Servers

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
Automate Certbot SSL Renewals with Nginx & Apache Cron

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.

For Nginx

sudo certbot --nginx -d example.com -d www.example.com

Explanation:

  • --nginx – selects the Nginx plugin.
  • -d example.com -d www.example.com – lists the domains to secure.
  • Certbot creates a temporary HTTP challenge, obtains the certificate, and updates Nginx server blocks with ssl_certificate and ssl_certificate_key.

For Apache

sudo certbot --apache -d example.com -d www.example.com

Explanation:

  • --apache – selects the Apache plugin.
  • The plugin edits the relevant VirtualHost sections, adding SSLCertificateFile and SSLCertificateKeyFile directives.

When prompted, choose to redirect HTTP traffic to HTTPS. This is the recommended secure default.

Verifying the Installation

After Certbot completes, confirm the certificate is active.

# For Nginx
sudo nginx -t          # checks syntax
sudo systemctl reload nginx

# For Apache
sudo apachectl configtest   # checks syntax
sudo systemctl reload apache2

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:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

Automating Renewal with Cron

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

Make both scripts executable:

sudo chmod +x /usr/local/sbin/certbot-renew.sh
sudo chmod +x /usr/local/sbin/certbot-deploy.sh

3. Add a Cron Entry

Edit the root crontab:

sudo crontab -e

Insert the following line to run the renewal script twice daily:

30 2,14 * * * /usr/local/sbin/certbot-renew.sh >> /var/log/certbot-renew.log 2>&1

Explanation of the cron fields:

  • 30 – minute.
  • 2,14 – hour (2 AM and 2 PM).
  • * * * – 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.

lets encryptcertbotssl certificatehttpsnginxapachelinux serverdomain security

Try it on your own server

Follow along on a Cloud VPS with full root access, or read the step-by-step knowledge base guides.