Renewed Certbot files under /etc/letsencrypt/live/ do not automatically change the certificate already opened by a long-running Apache process. Add a deploy hook so Apache reloads after a successful renewal and starts serving the renewed certificate without waiting for the next manual service change.
Certbot deploy hooks run after a certificate is renewed successfully, which makes them a better fit than a post hook when the only job is to reload the web server after certificate material changes. Directory hooks under /etc/letsencrypt/renewal-hooks/deploy/ are also picked up by normal automated renewals, so the reload stays attached to the renewal process instead of living in a separate cron entry.
The commands below use the Debian and Ubuntu Apache layout with apache2ctl and the apache2 service name. Test the Apache configuration inside the hook before reloading; a renewed certificate path is not useful if a separate virtual host error would make the reload fail.
Related: Test Certbot certificate renewal
Related: Check the Certbot renewal timer
Related: Manage the Apache service
Steps to reload Apache after Certbot renewal:
- Confirm that the Apache service is running before wiring the renewal hook.
$ sudo systemctl is-active apache2 active
If Apache is not active, fix the service state first. A renewal hook should reload the running web server after certificate changes, not hide an already-stopped service.
Related: Manage the Apache service
- Test the current Apache configuration.
$ sudo apache2ctl configtest Syntax OK
A fresh Debian or Ubuntu host may print the AH00558 fully qualified domain name warning before Syntax OK. The final Syntax OK line is the parser result; fix real syntax errors before adding the hook.
Related: Test Apache configuration
- Create the Certbot deploy-hook directory if it does not already exist.
$ sudo install -d -m 755 /etc/letsencrypt/renewal-hooks/deploy
Deploy hooks in this directory run after successful renewals. Use /etc/letsencrypt/renewal-hooks/post/ only for work that should happen after every renewal attempt, including failed attempts.
- Move into the deploy-hook directory.
$ cd /etc/letsencrypt/renewal-hooks/deploy
- Create the Apache reload hook file.
$ sudo vi reload-apache.sh
- Add a syntax test followed by a service reload.
- reload-apache.sh
#!/bin/sh set -eu /usr/sbin/apache2ctl configtest /usr/sbin/apache2ctl graceful
apache2ctl graceful asks Apache to re-read its configuration and continue serving with a new worker generation. On RHEL-family systems, use the matching apachectl or httpd control path for that host.
- Make the hook executable.
$ sudo chmod 755 reload-apache.sh
- Run the hook manually before waiting for a real renewal.
$ sudo ./reload-apache.sh Syntax OK
apache2ctl graceful normally returns no output when it succeeds, so the visible success line is the Apache syntax test that ran before the graceful reload.
- Confirm that Apache stayed active after the manual hook test.
$ sudo systemctl is-active apache2 active
If the service is not active after the hook runs, inspect the Apache journal before retrying renewal tests.
- Test the renewal path with deploy hooks enabled for the dry run.
$ sudo certbot renew --dry-run --run-deploy-hooks Saving debug log to /var/log/letsencrypt/letsencrypt.log ##### snipped ##### Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/www.example.com/fullchain.pem (success)
Certbot dry runs do not run deploy hooks by default. The --run-deploy-hooks option makes the dry run execute deploy hooks so the Apache reload path is tested before the next real renewal.
Related: Test Certbot certificate renewal
- Confirm that the site is serving a renewed certificate after a real renewal.
$ openssl s_client -servername www.example.com \ -connect www.example.com:443 </dev/null 2>/dev/null | \ openssl x509 -noout -subject -dates subject=CN=www.example.com notBefore=Jun 12 00:00:00 2026 GMT notAfter=Sep 10 23:59:59 2026 GMT
Check the public hostname that users actually reach. Shared listeners, IPv6 records, reverse proxies, and load balancers can serve a different certificate than the local Apache process.
Tool: SSL Expiry Checker
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.