Keep (keephq) on-call/alerting — deployment runbook (GPU host ai-ahu)
Self-hosted Keep is the escalation/on-call layer for the platform's EWS
warnings, chosen after Grafana OnCall OSS was found archived (Mar 2026).
Deployed on the GPU host ai-ahu (192.168.83.20), VPN-only, on 2026-07-09.
The observatory's EWS notifier POSTs each warning to Keep as a per-alert
firing/resolved event; Keep owns grouping, escalation, ack, and on-call.
What's deployed
- Compose:
~/keep-deploy/compose.keep.ymlonai-ahu(projectkeep). Self-contained (not the upstream multi-file compose): telemetry (PostHog/Sentry) disabled, the optional grafana/prometheus profiles omitted (the host already runs its own on :3000/:9090). - Services (3):
keep-frontend(Next.js UI) — host192.168.83.20:8330→ :3000keep-backend(FastAPI API + ingestion) — host192.168.83.20:8331→ :8080keep-websocket-server(soketi, realtime UI) — host192.168.83.20:8332→ :6001- All bound to
192.168.83.20(VPN-reachable, NOT internet-exposed). - State: SQLite + file secret-manager in
~/keep-deploy/state(bind mount). Back up this dir to preserve alerts/config/API keys. - Auth:
AUTH_TYPE=DBsince 2026-08-13 — username/password login on both UI and API. Credentials in~/keep-deploy/keep-auth.env(mode 600, git-ignored). See2026-08-13-keep-auth-and-smtp-escalation.md. - UI: http://192.168.83.20:8330 (from the VPN) → login page.
How it's wired to the observatory
- Observatory
notificationsblock (live in~/ahu-ai-observatory/deploy/observatory.yaml):enabled: true,min_severity: warning,eval_interval_s: 300, singlewebhookchannel →http://192.168.83.20:8331/alerts/event(Keep's generic ingestion). Email channel left disabled — Keep owns escalation/ack, so no double-paging. - Ingestion auth:
KEEP_ALLOW_MESH_ALERT_INGESTION=trueon the backend → the host-internal observatory POSTs tokenless (the backend port is VPN-bound; not open to the internet). No API key to manage for ingestion. - Payload: Keep
AlertDto—name,status(firing|resolved),severity(critical|warning|info),lastReceived,fingerprint(= the observatory's stable warning fingerprintid|metric|subject),source: ["ahu-observatory"],description,labels(metric, subject, escalated). Keep dedups/auto-resolves byfingerprint.
Verified end-to-end (2026-07-09)
- Backend up (200); test firing alert →
202ingest → visible in Keep; same-fingerprintresolved→ the alert flipped to resolved (auto-resolve, no duplicate). - Live: the observatory notifier evaluated real warnings and Keep received them — e.g.
Kemungkinan probing / percobaan jailbreak(sec_error_probing) andVolume panggilan abnormal(sec_volume_outlier), firing/warning, grouped by fingerprint, with the actor aslabels.subject.
Ops
- Status/logs:
cd ~/keep-deploy && docker compose -f compose.keep.yml ps·... logs -f keep-backend - Restart/stop:
docker compose -f compose.keep.yml restart·... down(state persists in./state) - Read API (needs a real token since auth was enabled): POST
/signinwith thekeep-auth.envcredentials, then sendAuthorization: Bearer <accessToken>. The oldX-API-KEY:keepappkeytrick worked only because NO_AUTH accepted any key; it now returns 401. - Configure escalation/on-call: in the Keep UI (http://192.168.83.20:8330) — workflows, escalation policies, on-call schedules, ack, silence. This is where the "escalation workflow" lives (deliberately not rebuilt in our dashboard).
Hardening backlog (before real production reliance)
- ~~Enable auth.~~ DONE 2026-08-13 —
AUTH_TYPE=DB. Note what this closed: NO_AUTH had already seeded a userkeepwith roleadminand the default passwordkeep, so the instance was oneAUTH_TYPEflip away from a default-credential admin login. That user is now renamedadminwith a generated password, andkeep/keepreturns 401. - Postgres, not SQLite. SQLite single-node is fine for MVP; point
DATABASE_CONNECTION_STRINGat a Postgres for durability/scale (the host already runs Postgres/Timescale). - Pin image tags. Currently
:latestfor keep-ui/keep-api — pin to a released version so a rebuild can't drift. - Notification transports out of Keep. Prepared, blocked on one input.
deploy/keep/setup-smtp.shinstalls the SMTP provider + the email escalation workflow and verifies delivery in one command — it needs a relay host/credential and a routable recipient, which do not exist on this host yet. Until then Keep has 0 providers and 0 workflows, i.e. alerts are collected and deduped but nobody is paged. See2026-08-13-keep-auth-and-smtp-escalation.md. - Edge DNS (optional): front the UI with an edge vhost (like the dashboard's
x056.ahu-demo.dashboard.val.id) if browser access beyond the VPN is wanted. - Resource limits + backups: add compose
mem_limit/cpusand a periodic backup of~/keep-deploy/state.
Rollback
Disable the observatory notifier (notifications.enabled: false in observatory.yaml + docker compose restart observatory; backup observatory.yaml.bak-pre-keep), and/or stop Keep (docker compose -f ~/keep-deploy/compose.keep.yml down). The observatory is byte-identical to pre-notifier when disabled.