cc31c993dd
The chart asked for a whole DSN in a Secret. Nothing writes one: the Zalando postgres operator generates a Secret with `username` and `password` keys and no connection string, so wiring the wrapper chart up would have meant hand-maintaining a second copy of a password the operator owns and rotates on a from-scratch rebuild -- which is charts#176 again, the issue miniflux closed by doing the opposite. So the DSN becomes a plain value with no password in it, and the password arrives as PGPASSWORD from a Secret. pgx fills in from libpq's PG* environment variables whatever the DSN omits, exactly as miniflux's lib/pq does. Verified rather than assumed, against a real server: a password-less DSN connects with PGPASSWORD set, and fails with `password authentication failed` when it is wrong, so the variable is doing the work rather than being quietly ignored. It also keeps the credential out of the rendered manifest and out of `kubectl describe pod`, which a DSN-with-password does not.
121 lines
5.1 KiB
YAML
121 lines
5.1 KiB
YAML
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 — `<user>.<cluster>.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://<networking.hostname>.
|
|
#
|
|
# 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 <fullname>-admin-key
|
|
secretName: ""
|