Dead man's switch: HTTP heartbeat listener that rings a Discord webhook when a beat falls silent
8.6K
A dead man's switch in a single tiny container: things ping it while they're alive, and when the pings stop, it rings a Discord webhook.
Monitoring tells you when something visibly breaks. It stays quiet when the thing that was supposed to run simply never ran: the cron job that silently stopped, the alerting pipeline that died along with its own ability to alert. knell watches for that silence.
You configure named beats, each with a deadline. Anything that can send an HTTP request pings its beat (POST /beat/<id>); if a beat stays silent past its deadline, knell posts a missing notice to your Discord webhook, and a recovered notice when the pings return. Per-beat freshness is also exposed as Prometheus metrics, so a metrics stack can aggregate several knell instances into quorum views.
scratch base: no shell, no libc, no dependencies to patchdocker pull cplieger/knell:latest
Also published to ghcr.io/cplieger/knell with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.
# Example compose for knell. See the README for all configuration options and hardening.
services:
knell:
image: ghcr.io/cplieger/knell:latest
container_name: knell
restart: unless-stopped
environment:
BEATS: "cron-backup:26h,pipeline-watchdog:20m" # id:deadline list, see README
DISCORD_WEBHOOK_URL: "https://discord.com/" # invalid placeholder; replace with the full Discord webhook URL
BEAT_TOKEN: "CHANGEME" # invalid placeholder; replace with: openssl rand -hex 16
NODE_NAME: "server-1" # names this observer in notifications
ports:
# /metrics is unauthenticated and enumerates beats; set ALLOWED_HOSTS
# and restrict exposure -- see README "Configuration reference".
- "9190:9190"
GPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.
Content type
Image
Digest
sha256:b7a736da5…
Size
3.4 MB
Last updated
about 4 hours ago
docker pull cplieger/knell