Use a deploy hook to reload your web server. Certbot runs it only after a successful renewal, so you avoid needless reloads. Pre and post hooks run around every renewal attempt, whether or not a certificate was renewed. A server that is never reloaded keeps serving the old certificate until it expires.
The three hook types
The Certbot documentation explains the difference. When Certbot detects that a certificate is due for renewal, pre hook and post hook commands run before and after each attempt to renew. If you want a command to run only after a successful renewal, use a deploy hook.
| Hook | Runs | Typical use |
|---|---|---|
| Pre | Before each renewal attempt | Stop something that holds port 80 |
| Post | After each renewal attempt | Start that thing again |
| Deploy | Only after a successful renewal | Reload the server so it uses the new certificate |
Because renewal is only attempted when a certificate is due, these hooks do not fire on every timer run, but a failed attempt still triggers pre and post.
Two ways to configure hooks
You can pass a deploy hook on the command line when running the renew command, with a path to your script. Or you can place executable files in subdirectories of Certbot's configuration directory. With the usual configuration directory, executables in the renewal hooks folders named pre, deploy and post under /etc/letsencrypt run as pre, deploy and post hooks. They run in alphabetical order.
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/deploy/reload-web.sh
systemctl reload nginx
Make the file executable. Reload, not restart, keeps existing connections alive. See reloading nginx without downtime.
Why deploy beats post for reloads
A post hook also runs after a failed attempt. Reloading after a failure is usually harmless, but it can mask problems: the reload succeeds, the logs look busy, and nobody notices that the certificate never changed. A deploy hook ties the action to the event you care about.
Pre hooks are for cases such as the standalone mode, where Certbot needs a free port. If you use a webroot or a server plugin, you rarely need one.
Checklist for a hook that works
- The script is executable and has the correct interpreter line.
- It uses absolute paths, since cron and timers run with a small environment.
- It exits nonzero on failure, and you read the exit status.
- It reloads every process that holds the certificate, including mail servers and proxies that share the files, not just the web server.
- You tested with a dry run. See testing a renewal before it fails.
- You check the served certificate afterwards, not just the files. See checking expiry with openssl.
Is renewal even scheduled?
The documentation says to check whether your installation method already installed a timer. Look for the renew command in the system crontab or in systemd timers. It also notes that Certbot is designed to cope with both a preinstalled timer and a manual one existing together. For containers, remember that a timer must run somewhere that persists, as covered in the ACME renewal checklist.
Where Safeguard fits
Safeguard does not run Certbot. It provides SBOM and dependency scanning plus policies and gates over the repositories where hook scripts live. Free scan: gold.safeguard.sh/scan.
Quick check
Does a deploy hook run if renewal fails?
No. It runs only after a successful renewal.
In what order do hook files run?
Alphabetical order, within each hook folder.
Should I restart or reload?
Reload where the server supports it, since it applies the new certificate without dropping connections.
Sources
Last reviewed: 19 October 2026.