“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
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
Check what you got:
sudo certbot certificates
🧠 Heads-up:
--standalone
runs a temporary HTTP server on port 80.
If you're using Nginx or Docker, stop them first or use--webroot
.
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
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
Test if it works:
sudo certbot renew --dry-run
You should see something like:
Certbot dry-run was successful.
📅 Certbot renews certificates when they’re 30 days from expiry.
Latest update logs:
journalctl -u certbot.service --no-pager --since "2 days ago"
🧓 Prefer old-school cron? No problem
Disable the timer:
sudo systemctl stop certbot.timer
sudo systemctl disable certbot.timer
Then add this to your crontab (sudo crontab -e
):
0 0 1 * * /usr/bin/certbot renew --standalone --quiet
To find out the exact path to certbot
, use:
which certbot
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
Add:
pre_hook = systemctl stop your-app.service
deploy_hook = systemctl reload your-app.service
post_hook = systemctl start your-app.service
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."
Crontab it like a boss:
0 0 1 * * /bin/bash /home/you/scripts/renew-ssl.sh >> /var/log/certbot.log 2>&1
🧠 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.
Top comments (1)
Very Helpful Article