Niklas Ye 36468a68ed chart: add bootstrap job (v0.2.0)
Post-install/post-upgrade Job that calls /api/bootstrap on first deploy
and stores the admin API key in a Secret (<release>-admin-key by default).
Exits cleanly on subsequent upgrades when bootstrap is already complete.
Adds ServiceAccount, Role (secrets:create), and RoleBinding as hook resources.
2026-05-22 10:11:30 +02:00

Terminal Duty (terdut-server)

On-call alert management server for teams using Prometheus Alertmanager.

  • Receives Alertmanager webhooks directly — no adapter needed
  • Stores and queries alerts (acknowledge, comment)
  • On-call schedule management (user-to-day assignments)
  • Alert statistics (by status, by hour, by day)
  • REST API with per-user API key authentication
  • Single binary, SQLite storage — trivial to self-host

Quick start

Prerequisites: Go 1.21+

git clone https://github.com/yeniklas/terdut-server
cd terdut-server
go run ./cmd/terdut

The server starts on :8080 with a terdut.db file in the working directory.

Create the first user

curl -X POST http://localhost:8080/api/bootstrap \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "email": "admin@example.com"}'

Save the api_key.key value from the response — it is shown once only.

Use it as a bearer token for all subsequent requests:

export KEY=<your-key>
curl -H "Authorization: Bearer $KEY" http://localhost:8080/api/users

Docker

docker build -t terdut-server .
docker run -p 8080:8080 -v $(pwd)/data:/data \
  -e TERDUT_DB_PATH=/data/terdut.db \
  terdut-server

Configuration

Variable Default Description
TERDUT_ADDR :8080 TCP address to listen on
TERDUT_DB_PATH terdut.db Path to the SQLite database file

Alertmanager configuration

Add terdut-server as a webhook receiver in your alertmanager.yml:

receivers:
  - name: terdut
    webhook_configs:
      - url: http://terdut-server:8080/api/alertmanager/webhook
        send_resolved: true

route:
  receiver: terdut

The webhook endpoint requires no authentication.


API reference

Authentication

All endpoints except /api/bootstrap and /api/alertmanager/webhook require:

Authorization: Bearer <api-key>

Users

Method Path Description
POST /api/bootstrap Create first user + API key (only works on empty DB)
GET /api/users List users
POST /api/users Create user {"username","email"}
DELETE /api/users/{id} Delete user (cascades to keys)
POST /api/users/{id}/api-keys Issue API key {"name"} — key shown once
DELETE /api/users/{id}/api-keys/{keyID} Revoke API key

Alert ingestion

Method Path Description
POST /api/alertmanager/webhook Alertmanager v4 webhook receiver (no auth)

Alerts

Method Path Description
GET /api/alerts List alerts. Filters: ?status=firing|resolved, ?name=, ?from=YYYY-MM-DD, ?to=YYYY-MM-DD, ?limit= (default 50, max 500)
GET /api/alerts/{id} Get single alert
POST /api/alerts/{id}/acknowledge Acknowledge alert (stamps authed user + time)
DELETE /api/alerts/{id}/acknowledge Clear acknowledgement
GET /api/alerts/{id}/comments List comments (chronological)
POST /api/alerts/{id}/comments Add comment {"content"}
DELETE /api/alerts/{id}/comments/{commentID} Delete own comment

On-call schedule

Method Path Description
POST /api/schedule Assign user to dates {"user_id", "dates":["YYYY-MM-DD",...]} — all-or-nothing
GET /api/schedule List entries. Filters: ?from=YYYY-MM-DD, ?to=YYYY-MM-DD
GET /api/schedule/current Today's on-call user (UTC), 404 if none
DELETE /api/schedule/{id} Remove schedule entry

Statistics

All stat endpoints accept optional ?from=YYYY-MM-DD and ?to=YYYY-MM-DD to filter by received_at.

Method Path Description
GET /api/stats/alerts {total, firing, resolved} counts
GET /api/stats/alerts/top Most frequent alert names. ?limit= (default 10, max 100)
GET /api/stats/alerts/by-hour Count per hour-of-day (UTC), all 24 slots returned
GET /api/stats/alerts/by-day Count per day-of-week, all 7 slots with names returned

Development

go test ./...        # run all tests
go build ./...       # compile all packages
go run ./cmd/terdut  # run locally
S
Description
Incident management server for teams using Prometheus Alertmanager
Readme GPL-3.0 2.5 MiB
v0.32.0 Latest
2026-09-27 20:09:59 +00:00
Languages
Go 68.5%
JavaScript 23.4%
CSS 5.2%
Makefile 1.5%
HTML 1%
Other 0.4%