TLS certificate expiry monitor with ntfy alerts
  • Python 99.1%
  • Dockerfile 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Vela f20890f550
All checks were successful
CI / test (push) Successful in 10s
Send ntfy title as query param; non-ASCII header broke every alert
http.client encodes headers as latin-1, so the em dash in
'Sextant — Certificate Alert' raised before any request was sent.
Sextant has never delivered an alert. Tests mocked urlopen and missed
it; the new regression test goes through a real local HTTP server.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-20 15:33:35 -03:00
.forgejo/workflows Add Forgejo CI workflow 2026-08-16 20:53:12 -04:00
.github/workflows Initial release — TLS certificate expiry monitor with ntfy alerts 2026-08-16 18:48:00 -04:00
tests Send ntfy title as query param; non-ASCII header broke every alert 2026-10-20 15:33:35 -03:00
.gitignore Initial release — TLS certificate expiry monitor with ntfy alerts 2026-08-16 18:48:00 -04:00
Dockerfile Add Docker healthcheck for container health monitoring 2026-08-16 22:35:49 -04:00
LICENSE Initial release — TLS certificate expiry monitor with ntfy alerts 2026-08-16 18:48:00 -04:00
README.md Add NTFY_MAX_PRIORITY to cap alert priority 2026-10-20 14:35:58 -03:00
sextant.py Send ntfy title as query param; non-ASCII header broke every alert 2026-10-20 15:33:35 -03:00

Sextant

CI Release Container

TLS certificate expiry monitor with ntfy push notifications.

Part of the Docker monitoring suite: Lookout (container lifecycle) · Beacon (status page) · Bosun (log alerts) · Sextant (certificate expiry) · Drift (image updates)

Features

  • Monitors TLS certificate expiry for any number of HTTPS endpoints
  • Configurable warning and critical thresholds
  • Push notifications via ntfy with priority levels (urgent/high/default)
  • Alert cooldown prevents notification floods
  • Zero dependencies — Python stdlib only
  • Single file, Docker-native

Quick Start

docker run -d \
  --name sextant \
  -e ENDPOINTS="example.com,mysite.org:8443" \
  -e NTFY_URL="http://ntfy:80" \
  -e NTFY_TOPIC="certs" \
  ghcr.io/agent-cyanez/sextant

Configuration

All configuration via environment variables:

Variable Default Description
ENDPOINTS (required) Comma-separated list of host[:port] to monitor. Default port is 443.
CHECK_INTERVAL 3600 Seconds between check cycles
TIMEOUT 10 Connection timeout in seconds
WARN_DAYS 30 Days before expiry to send warning
CRIT_DAYS 7 Days before expiry to send critical alert
NTFY_URL http://127.0.0.1:8888 ntfy server URL
NTFY_TOPIC sextant ntfy topic for notifications
NTFY_MAX_PRIORITY (none) Ceiling for alert priority (min, low, default, high, urgent). Set to default to keep high/urgent free for messages a human must see
ALERT_COOLDOWN 86400 Seconds between repeat alerts for the same endpoint

Alert Priorities

Condition ntfy Priority
Certificate expired urgent
Connection failed urgent
Days left ≤ CRIT_DAYS high
Days left ≤ WARN_DAYS default
Healthy No alert

Docker Compose

services:
  sextant:
    image: ghcr.io/agent-cyanez/sextant
    container_name: sextant
    restart: unless-stopped
    environment:
      - ENDPOINTS=example.com,mysite.org,api.example.com:8443
      - CHECK_INTERVAL=3600
      - WARN_DAYS=30
      - CRIT_DAYS=7
      - NTFY_URL=http://ntfy:80
      - NTFY_TOPIC=certs

Development

python3 -m unittest discover -s tests -v

License

MIT