networking: hostname: "terdut.example.com" servicePort: 8080 # Gateway listener to bind the HTTPRoute to. Empty attaches to every matching # listener, including plaintext HTTP. Set this to the name of the HTTPS # listener to serve the API over TLS only. listener: "" image: repository: git.ryuvia.com/niklas/terdut-server tag: "latest" pullPolicy: IfNotPresent # Postgres connection. The chart provisions no database; it expects one to exist. database: # Required. A DSN with no password in it: # postgres://terdut@terdut-postgres:5432/terdut?sslmode=require # # The password is deliberately a separate setting. pgx falls back to libpq's # environment variables for anything the DSN omits, so PGPASSWORD supplies it # without the credential appearing in values, in the rendered manifest, or in # `kubectl describe pod`. dsn: "" # Where PGPASSWORD comes from. With the Zalando postgres operator this is the # Secret it generates for the role — `..credentials.postgresql.acid.zalan.do`, # whose keys are `username` and `password` — so a from-scratch rebuild mints a # new password and the server picks it up with nothing to keep in sync. # # Read at process start only: rotating the password needs a pod restart. # # Leave name empty only if the DSN carries its own password, which puts it in # the manifest. passwordSecret: name: "" key: password service: type: ClusterIP port: 8080 sweeper: # How long a firing alert may go without a refreshing webhook before it is # treated as resolved. Must exceed your Alertmanager repeat_interval. staleAfter: 6h # How long a resolved alert stays in the default list before auto-archiving. archiveAfter: 168h # Alerts treated as dead man's switches: receiving one opens no incident, and # the absence of one does. The Watchdog alert kube-prometheus-stack ships is # exactly this — an always-firing alert whose only value is something noticing # when it stops. deadman: # Which alerts to treat as heartbeats. ";" separates matchers, "," separates # the label conditions within one, "=" is exact equality. Every matcher must # name an alertname: # alertname=Watchdog,cluster=prod; alertname=EdgeHeartbeat # Each distinct label set is watched independently, so two clusters sending # the same alertname are two switches and a live one cannot mask a dead one. matchers: "alertname=Watchdog" # How long a heartbeat may go unheard before its switch is declared dead. # # This must be SHORTER than the Alertmanager repeat_interval of the route # carrying the heartbeat — the opposite of sweeper.staleAfter. The default # repeat_interval of 4h (12h in many setups) makes for a useless dead man's # switch, so give the heartbeat a route of its own: # # - matchers: [ 'alertname = "Watchdog"' ] # receiver: terdut # group_wait: 0s # group_interval: 1m # repeat_interval: 1m # # That delivers every 2m rather than every 1m: a group is only reconsidered # each group_interval, and at exactly one elapsed interval repeat_interval has # not quite passed, so equal values give 2x. Fine against 15m; use # group_interval: 30s if you want a true 1m. # # Set to 0 to disable dead man's switch handling entirely. timeout: 15m # Severity a dead man's switch incident opens at. These incidents have no # member alerts to derive one from, and the heartbeat's own severity label is # meaningless — Watchdog ships as "none". Only "critical" maps to the ntfy # priority that overrides a phone's quiet hours. severity: critical notify: # ntfy server that push notifications are published to, e.g. # http://ntfy.ntfy.svc.cluster.local. Empty disables notifications entirely. ntfyUrl: "" # Topic used when nobody is on call today. Notifications sent here carry no # Acknowledge button: the topic is shared, so there is no user to attribute an # acknowledgement to. Leave empty to send nothing when the schedule is unset. fallbackTopic: "" # How long an incident may sit unacknowledged before it is paged again. # Set to 0 to notify once and never repeat. repeatEvery: 15m # Base URL a phone uses to reach this server, for the link and the Acknowledge # button inside a notification. Defaults to https://. # # The Acknowledge button is a POST to /api/notify/ack/{token} from the # responder's phone, so that path has to stay publicly reachable — it is # authorised by the scoped token in the URL, not by network placement. publicUrl: "" # Optional bearer token for an access-controlled ntfy, read from an existing # Secret. Leave name empty for an open ntfy. tokenSecret: name: "" key: token # Backups are no longer this chart's business. The SQLite database lived on a PVC # beside the app, so it needed a sidecar with a sqlite3 module for k8up to exec a # dump in; Postgres is backed up where it runs, through a k8up.io/backupcommand # pg_dump annotation on the database pod itself. bootstrap: enabled: true username: admin email: admin@example.com # secretName overrides the default of -admin-key secretName: ""