The check is silent by design on a healthy host, so an absent alert is
indistinguishable from a cron that stopped running. Ping HEALTHCHECK_URL
on a clean run and the /fail endpoint when the check alerts or cannot
complete. Empty by default, which disables the pings.
certbot renews the file but nginx serves the old certificate from memory
until reloaded, so a disk-only check reports healthy while browsers get an
expired certificate. Compare each lineage against what nginx serves over
SNI on the loopback listener.
The comparison is gated on the served certificate's SAN list covering the
domain: nginx finishes the handshake with a fallback vhost certificate
when SNI matches nothing, which would otherwise compare a lineage against
an unrelated certificate and warn falsely.
Certbot renews at 30 days remaining, so a healthy certificate never falls
below it and the old 14 day threshold could only fire after renewal had
been broken for 16 straight days, leaving 14 days to react. 25 days fires
about five days after the first failed renewal.
The script posted alerts to https://ntfy.silverwal.com/certbot, which is
served by the same nginx whose certificates it monitors. A TLS failure on
this host would make curl -fsS fail verification and drop the alert
describing that failure, leaving only a line in a log nobody reads.
ntfy is already bound to 127.0.0.1:2586, so post there instead.
These were dropped in b1b4296 when the README was trimmed, which left no
record in the repo of how the script gets onto the server or how it is
scheduled.