A Certbot certificate can renew successfully while the service that uses it keeps serving the old certificate until it is reloaded or synced. Configure a deploy hook when a command must run only after Certbot has obtained a new certificate, not after every scheduled renewal check.
A deploy hook is different from a pre or post renewal hook. Certbot runs deploy hooks once for each successfully issued or renewed certificate, and the hook receives RENEWED_LINEAGE and RENEWED_DOMAINS so the script can act on the certificate that changed.
Use a certificate-specific hook when only one lineage needs the deployment action. Host-wide directory hooks belong under /etc/letsencrypt/renewal-hooks/deploy and are better when the same script should run for every renewed certificate on the server.
Related: List Certbot certificates
Related: Test Certbot certificate renewal
Related: Configure a Certbot renewal hook
Steps to configure a Certbot deploy hook:
- Open a terminal on the server that owns the Certbot certificate lineage.
- List the saved certificate names.
$ sudo certbot certificates Saving debug log to /var/log/letsencrypt/letsencrypt.log Found the following certs: Certificate Name: www.example.com Domains: www.example.com example.com Expiry Date: 2026-07-25 06:50:00+00:00 (VALID: 42 days) Certificate Path: /etc/letsencrypt/live/www.example.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/www.example.com/privkey.pemUse the value after Certificate Name with --cert-name. If no certificate appears, configure the deploy hook on the host where the certificate was issued or create the certificate before adding the hook.
- Create the deploy script in a root-owned executable path.
$ sudoedit /usr/local/sbin/deploy-certbot-web.sh
#!/bin/sh set -eu domains=${RENEWED_DOMAINS:-unknown} lineage=${RENEWED_LINEAGE:-unknown} printf 'Deploy hook ran for %s from %s\n' "$domains" "$lineage" systemctl reload nginxReplace systemctl reload nginx with the deployment command that must run after the renewed certificate is available. Keep the script non-interactive because automatic renewal may run from systemd or cron without a terminal.
- Make the deploy script executable.
$ sudo chmod 755 /usr/local/sbin/deploy-certbot-web.sh
- Test the script directly with sample deploy-hook variables.
$ sudo RENEWED_DOMAINS="www.example.com example.com" \ RENEWED_LINEAGE="/etc/letsencrypt/live/www.example.com" \ /usr/local/sbin/deploy-certbot-web.sh Deploy hook ran for www.example.com example.com from /etc/letsencrypt/live/www.example.com
Fix script, permission, service, or reload errors before attaching the script to Certbot. A failing hook prints an error, but the hook failure is not the same as a failed renewal.
- Attach the deploy hook to the selected certificate renewal configuration.
$ sudo certbot reconfigure \ --cert-name www.example.com \ --deploy-hook /usr/local/sbin/deploy-certbot-web.sh \ --run-deploy-hooks
certbot reconfigure updates the saved renewal configuration for one certificate name. --run-deploy-hooks makes the test path run deploy hooks if the dry-run renewal succeeds, and the hook uses the current active certificate files rather than the temporary staging certificate.
- Run a deploy-hook renewal test for the same certificate.
$ sudo certbot renew --cert-name www.example.com --dry-run --run-deploy-hooks Saving debug log to /var/log/letsencrypt/letsencrypt.log Processing /etc/letsencrypt/renewal/www.example.com.conf Simulating renewal of an existing certificate for www.example.com and example.com Deploy hook ran for www.example.com example.com from /etc/letsencrypt/live/www.example.com Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/www.example.com/fullchain.pem (success)
During --dry-run, deploy hooks run only when --run-deploy-hooks is included. A host without a saved renewal configuration for the certificate cannot prove the hook with this command.
- Let the normal renewal schedule call the deploy hook after the dry run succeeds.
$ sudo certbot renew Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No renewals were attempted. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A normal renewal check may do nothing when certificates are not near expiry. The deploy hook runs after Certbot actually issues or renews the matching certificate.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.