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.
86 lines
3.2 KiB
YAML
86 lines
3.2 KiB
YAML
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ include "terdut-server.fullname" . }}
|
|
labels:
|
|
{{- include "terdut-server.labels" . | nindent 4 }}
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
{{- include "terdut-server.selectorLabels" . | nindent 6 }}
|
|
# Recreate, not RollingUpdate, even though the PVC that forced it is gone: the
|
|
# sweeper and the notifier are unsynchronised singletons, and two replicas
|
|
# overlapping during a rollout would both page for the same incident.
|
|
strategy:
|
|
type: Recreate
|
|
template:
|
|
metadata:
|
|
labels:
|
|
{{- include "terdut-server.selectorLabels" . | nindent 8 }}
|
|
spec:
|
|
enableServiceLinks: false
|
|
containers:
|
|
- name: terdut-server
|
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
ports:
|
|
- name: http
|
|
containerPort: {{ .Values.service.port }}
|
|
protocol: TCP
|
|
env:
|
|
- name: TERDUT_ADDR
|
|
value: ":{{ .Values.service.port }}"
|
|
- name: TERDUT_DB_DSN
|
|
value: {{ required "database.dsn is required" .Values.database.dsn | quote }}
|
|
{{- if .Values.database.passwordSecret.name }}
|
|
# The password reaches pgx through libpq's environment variable
|
|
# rather than through the DSN, so it stays out of the rendered
|
|
# manifest. pgx fills in from PG* whatever the DSN leaves out.
|
|
- name: PGPASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Values.database.passwordSecret.name }}
|
|
key: {{ .Values.database.passwordSecret.key }}
|
|
{{- end }}
|
|
- name: TERDUT_STALE_AFTER
|
|
value: "{{ .Values.sweeper.staleAfter }}"
|
|
- name: TERDUT_ARCHIVE_AFTER
|
|
value: "{{ .Values.sweeper.archiveAfter }}"
|
|
- name: TERDUT_DEADMAN_MATCHERS
|
|
value: "{{ .Values.deadman.matchers }}"
|
|
- name: TERDUT_DEADMAN_TIMEOUT
|
|
value: "{{ .Values.deadman.timeout }}"
|
|
- name: TERDUT_DEADMAN_SEVERITY
|
|
value: "{{ .Values.deadman.severity }}"
|
|
{{- if .Values.notify.ntfyUrl }}
|
|
- name: TERDUT_NTFY_URL
|
|
value: "{{ .Values.notify.ntfyUrl }}"
|
|
- name: TERDUT_NTFY_FALLBACK_TOPIC
|
|
value: "{{ .Values.notify.fallbackTopic }}"
|
|
- name: TERDUT_NOTIFY_REPEAT
|
|
value: "{{ .Values.notify.repeatEvery }}"
|
|
- name: TERDUT_PUBLIC_URL
|
|
value: "{{ .Values.notify.publicUrl | default (printf "https://%s" .Values.networking.hostname) }}"
|
|
{{- if .Values.notify.tokenSecret.name }}
|
|
- name: TERDUT_NTFY_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Values.notify.tokenSecret.name }}
|
|
key: {{ .Values.notify.tokenSecret.key }}
|
|
{{- end }}
|
|
{{- end }}
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
|
|
|