The README was 1,240 lines of reference material and still described a SQLite quick start. It is now a short tour (highlights, screenshots of the web UI, an accurate quick start against Postgres), and each topic has its own page under docs/ with an index: deployment, configuration, Alertmanager, incidents, notifications, escalation, dead man's switches, single sign-on, web UI, API and development. SERVICE-ACCOUNTS.md is rewritten from a proposal into a reference, and TEAM-LOOKUP.md is gone with the endpoint it described. The "Upgrading to ..." sections for an unreleased product are dropped. Claude-Session: https://claude.ai/code/session_016mBLURvJoMuUEr9cB2RpUN
4.9 KiB
Configuration
Environment variables and settings. Back to the README and the documentation index.
Two kinds of setting, split by who changes them and how often.
Where the server is plugged in stays in the environment: the listen address, the database DSN, the ntfy URL and token, the public URL. They are needed before the database is open, and two of them are credentials.
How the server behaves lives in the database and is edited by an
administrator in the web UI or through PUT /api/admin/settings, taking effect
on the next sweep rather than at the next restart. The variables below marked
seed are the value each of those starts from: written once, on first start,
and never overwritten afterwards — a redeploy cannot put a chart's default back
over an administrator's edit.
| Variable | Default | Description |
|---|---|---|
TERDUT_ADDR |
:8080 |
TCP address to listen on |
TERDUT_DB_DSN |
— | Required. Postgres connection string, e.g. postgres://terdut:secret@localhost:5432/terdut?sslmode=require |
TERDUT_ARCHIVE_AFTER |
168h (7d) |
seed. How long a resolved alert or incident stays in the default list before being auto-archived |
TERDUT_STALE_AFTER |
6h |
seed. How long a firing alert may go without a refreshing webhook before it is treated as resolved — must exceed your Alertmanager repeat_interval |
TERDUT_NTFY_URL |
— | ntfy server to publish push notifications to. Empty disables notifications entirely |
TERDUT_NTFY_TOKEN |
— | Bearer token for an access-controlled ntfy |
TERDUT_NTFY_FALLBACK_TOPIC |
— | Topic used when nobody is on call |
TERDUT_PUBLIC_URL |
— | Base URL a phone uses to reach this server: the notification's link into the web UI, its Acknowledge button, and whether the session cookie is Secure |
TERDUT_NOTIFY_REPEAT |
15m |
seed. How long an incident may sit unacknowledged before it is paged again. 0 notifies once and never repeats |
TERDUT_PASSWORD_LOGIN |
true |
false refuses password login and password sign-up (403), leaving single sign-on the only way in. Refused at startup unless SSO is configured |
TERDUT_TRUSTED_PROXIES |
1 |
How many reverse proxies in front of the server append to X-Forwarded-For; the per-address rate limits use the entry that many hops from the right. 0 ignores the header |
TERDUT_OPERATOR_KEY |
— | At least 32 characters. When set, the instance-scoped service account terdut-operator is created if missing and its seed key replaced with this value at every start — how terdut-operator authenticates without a bootstrap handshake. An instance-scoped account acts as owner of every team (team configuration) but is not a member of any, so it reads no incidents |
TERDUT_OPERATOR_MODE |
false |
Declares this install gitops-managed: a session's or a user's own API key's writes to teams, escalation policies, dead man's switches and integrations are refused (403 reason:"operator_managed"); a service account's are not. Team membership and the schedule stay editable regardless |
TERDUT_OIDC_ISSUER |
— | Turns single sign-on on. The provider's issuer URL; discovery is read from <issuer>/.well-known/openid-configuration. See Single sign-on |
TERDUT_OIDC_CLIENT_ID / TERDUT_OIDC_CLIENT_SECRET |
— | Required with an issuer. The confidential client registered at the provider. Keep the secret in a Secret, not in values |
TERDUT_OIDC_NAME |
SSO |
What the sign-in button calls the provider |
TERDUT_OIDC_SCOPES |
openid profile email |
Scopes requested, comma or space separated. Authentik puts groups behind profile |
TERDUT_OIDC_USERNAME_CLAIM / _EMAIL_CLAIM / _GROUPS_CLAIM |
preferred_username / email / groups |
ID token claims read for the username, email and groups |
TERDUT_OIDC_TRUST_EMAIL |
false |
Link a first sign-in to an existing local user by email even if the provider does not mark the address verified |
TERDUT_OIDC_ALLOWED_GROUPS |
— | Comma-separated. Only people in one of these may sign in. Empty admits everybody the provider authenticates |
TERDUT_OIDC_ADMIN_GROUP |
— | Members are system administrators |
TERDUT_OIDC_SESSION_MAX_AGE |
12h |
Hard ceiling on a session made by an SSO sign-in |
Durations use Go syntax (30m, 12h, 168h). An unparseable value falls back to the default.
Note that TERDUT_STALE_AFTER and a dead man's switch timeout point in opposite directions. Staleness
is a generous grace period around a repeat_interval you do not control; a dead man's switch is a
deadline you set deliberately, and the heartbeat's route is configured to beat faster than it.
In the Helm chart the two sweeper durations are set via sweeper.staleAfter and sweeper.archiveAfter, notifications via the notify.* values, single sign-on via oidc.* and passwordLogin, and operator mode via operatorMode.