The snap's snap.certbot.renew.timer (systemd Timers) runs certbot renew twice a day. A certificate is due when a third of its lifetime remains (half, under ten days) unless the CA's ACME Renewal Information (ARI, RFC 9773) says otherwise; Pebble 789 's log shows Certbot 1,690 querying /renewalInfo/. Apache 129 reads certificates only at start or reload, so add a deploy hook and test the whole chain:
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh <<'EOF'
#!/bin/sh
echo "deployed $RENEWED_LINEAGE" | logger -t certbot-deploy
systemctl reload apache2
EOF
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh
sudo certbot renew --dry-run --run-deploy-hooks --server https://localhost:14000/dir
journalctl -t certbot-deploy -o catOutput
Simulating renewal of an existing certificate for example.com and www.example.com Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/example.com/fullchain.pem (success) deployed /etc/letsencrypt/live/example.com
Two traps surfaced. --dry-run ignores the saved server = line and uses Let's Encrypt 1,144 staging, so Pebble needed --server; on a real server, plain sudo certbot renew --dry-run is right. And without a terminal, certbot renew first sleeps 1 to 480 seconds (397 here) to spread load.