DEV Community

Cover image for How to Automatically Renew Let’s Encrypt SSL Certs with Certbot on Ubuntu 🔐
Dima Zaichenko
Dima Zaichenko

Posted on

How to Automatically Renew Let’s Encrypt SSL Certs with Certbot on Ubuntu 🔐

“I’m not a DevOps engineer, but I play one in production.”

Tired of manually renewing SSL certs every 90 days like it’s a Tamagotchi from 2005?

This guide is for you: developers who want HTTPS without DevOps nightmares.


🤔 Why Certbot?

Because:

  • It's free (thanks, Let's Encrypt).
  • It works (thanks, Certbot).
  • It renews itself (mostly).
  • And most importantly: you can get back to writing code instead of deciphering NGINX logs at 3AM.

🧪 Step 1 — Install Certbot

sudo apt update sudo apt install certbot 
Enter fullscreen mode Exit fullscreen mode

Boom. That’s it. The easy part.


📜 Step 2 — Get your first SSL cert

sudo certbot certonly --standalone \ -d yourdomain.com -d www.yourdomain.com 
Enter fullscreen mode Exit fullscreen mode

Check what you got:

sudo certbot certificates 
Enter fullscreen mode Exit fullscreen mode

🧠 Heads-up: --standalone runs a temporary HTTP server on port 80.

If you're using Nginx or Docker, stop them first or use --webroot.

Image description

More information about plugins can be found in the official documentation.


🔁 Step 3 — Let it renew itself (like magic)

Certbot installs a systemd timer by default:

systemctl list-timers | grep certbot 
Enter fullscreen mode Exit fullscreen mode

You can see output like:

Mon 2025-03-10 03:12:00 UTC 10h left Mon 2025-03-09 03:12:00 UTC certbot.timer certbot.service 
Enter fullscreen mode Exit fullscreen mode

Test if it works:

sudo certbot renew --dry-run 
Enter fullscreen mode Exit fullscreen mode

You should see something like:

Certbot dry-run was successful. 
Enter fullscreen mode Exit fullscreen mode

📅 Certbot renews certificates when they’re 30 days from expiry.

Latest update logs:

journalctl -u certbot.service --no-pager --since "2 days ago" 
Enter fullscreen mode Exit fullscreen mode

🧓 Prefer old-school cron? No problem

Disable the timer:

sudo systemctl stop certbot.timer sudo systemctl disable certbot.timer 
Enter fullscreen mode Exit fullscreen mode

Then add this to your crontab (sudo crontab -e):

0 0 1 * * /usr/bin/certbot renew --standalone --quiet 
Enter fullscreen mode Exit fullscreen mode

To find out the exact path to certbot, use:

which certbot 
Enter fullscreen mode Exit fullscreen mode

Because nothing says “legacy and proud” like a 1AM cron job.


🧙 Use Hooks Like a Wizard

Automatically stop/start your services when certs are renewed.

Open your renewal config:

sudo nano /etc/letsencrypt/renewal/yourdomain.com.conf 
Enter fullscreen mode Exit fullscreen mode

Add:

pre_hook = systemctl stop your-app.service deploy_hook = systemctl reload your-app.service post_hook = systemctl start your-app.service 
Enter fullscreen mode Exit fullscreen mode

Perfect when you want Certbot to renew certs and do the dishes.


🛠 Bonus: Bash Script of Champions

This is what you actually wanted — a copy-pasteable script to handle everything:

#!/bin/bash APP_PATH="/home/you/yourapp" DOMAIN="yourdomain.com" FULL_CHAIN="/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" PRIVATE_KEY="/etc/letsencrypt/live/${DOMAIN}/privkey.pem" CRT_DEST="${APP_PATH}/ssl/${DOMAIN}.crt" KEY_DEST="${APP_PATH}/ssl/${DOMAIN}.key" echo "[$(date)] Stopping the service..." systemctl stop your-app.service echo "Renewing certs silently..." /usr/bin/certbot renew --standalone --quiet echo "Copying certs like a pro..." cp -f "$FULL_CHAIN" "$CRT_DEST" cp -f "$PRIVATE_KEY" "$KEY_DEST" chmod 644 "$CRT_DEST" "$KEY_DEST" echo "Starting the service again..." systemctl start your-app.service echo "🎉 All done. Go grab a coffee." 
Enter fullscreen mode Exit fullscreen mode

Crontab it like a boss:

0 0 1 * * /bin/bash /home/you/scripts/renew-ssl.sh >> /var/log/certbot.log 2>&1 
Enter fullscreen mode Exit fullscreen mode

🧠 Final Thoughts

SSL shouldn't be harder than writing JavaScript regex.

Certbot + Let’s Encrypt is one of those rare tools that actually “just works” — if you let it.

✅ Works with cron

✅ Supports systemd

✅ Has deploy hooks

✅ Costs $0

Just test it every now and then. Let automation do its thing.

And for the love of uptime — back up your certs.


✨ Bonus Links

Top comments (1)

Collapse
 
bladearya profile image
Amit Kumar Rout

Very Helpful Article