From 8e2840b29dcfe4c4ce3e8dc2e2b729b5eb4a74e4 Mon Sep 17 00:00:00 2001 From: Maurice Date: Sun, 6 Sep 2026 17:25:35 +0200 Subject: [PATCH] docs(helm): document the probes block, and survive probes being nulled A probe map is exactly the value someone reaches for when their cluster is unhappy, so the two ways of reaching for it should not break the render. `probes: null` hit a nil pointer on `.Values.probes.liveness`; guarding with `with (default dict ...)` also makes dropping a single probe work, which is what you want on a pod whose liveness check is the thing killing it. The rest is documentation the chart already gives every other value: a wiki section next to Resource Limits, a Notes bullet, and a values comment naming the one trap here, that a handler switch has to clear the shipped httpGet in the same override or the API refuses the pod. Verified with helm template: defaults render byte for byte what the chart produced before, probes=null renders no probes, probes.liveness=null leaves one, and helm lint passes. --- charts/README.md | 1 + charts/trek/templates/deployment.yaml | 8 ++++++-- charts/trek/values.yaml | 6 +++++- wiki/Install-Helm.md | 12 ++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/charts/README.md b/charts/README.md index 48b341b6a..876d7b824 100644 --- a/charts/README.md +++ b/charts/README.md @@ -46,6 +46,7 @@ See `values.yaml` for more options. - With `persistence.enabled: false`, the data and uploads volumes use an `emptyDir` — storage is ephemeral and lost on pod restart. Intended for testing only. - `JWT_SECRET` is managed entirely by the server — auto-generated into the data PVC on first start and rotatable via the admin panel (Settings → Danger Zone). No Helm configuration needed. - `ENCRYPTION_KEY` encrypts stored secrets (API keys, MFA, SMTP, OIDC) at rest. Recommended: set via `secretEnv.ENCRYPTION_KEY` or `existingSecret`. If left empty, the server falls back automatically: existing installs use `data/.jwt_secret` (no action needed on upgrade); fresh installs auto-generate a key persisted to the data PVC. +- Liveness and readiness probes are configurable under `probes`. Overrides are merged over the defaults, so `--set probes.liveness.initialDelaySeconds=60` keeps the `httpGet` handler. When switching to `exec` or `tcpSocket`, clear `httpGet` in the same override. Set `probes.liveness: null` to remove a probe. - If using ingress, you must manually keep `env.ALLOWED_ORIGINS` and `ingress.hosts` in sync to ensure CORS works correctly. The chart does not sync these automatically. - Set `env.ALLOW_INTERNAL_NETWORK: "true"` if Immich or other integrated services are hosted on a private/RFC-1918 address (e.g. a pod on the same cluster or a NAS on your LAN). Loopback (`127.x`) and link-local/metadata addresses (`169.254.x`) remain blocked regardless. - `FORCE_HTTPS` is optional. Set `env.FORCE_HTTPS: "true"` only when ingress (or another proxy) terminates TLS. It enables HTTPS redirects, HSTS, CSP `upgrade-insecure-requests`, and forces the session cookie `secure` flag. Requires `TRUST_PROXY` to be set. diff --git a/charts/trek/templates/deployment.yaml b/charts/trek/templates/deployment.yaml index cc903eab1..7b24b98dd 100644 --- a/charts/trek/templates/deployment.yaml +++ b/charts/trek/templates/deployment.yaml @@ -80,10 +80,14 @@ spec: mountPath: /app/data - name: uploads mountPath: /app/uploads + {{- with (default dict .Values.probes).liveness }} livenessProbe: - {{- toYaml .Values.probes.liveness | nindent 12 }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (default dict .Values.probes).readiness }} readinessProbe: - {{- toYaml .Values.probes.readiness | nindent 12 }} + {{- toYaml . | nindent 12 }} + {{- end }} volumes: - name: data {{- if .Values.persistence.enabled }} diff --git a/charts/trek/values.yaml b/charts/trek/values.yaml index c127e72fe..7375cb4ed 100644 --- a/charts/trek/values.yaml +++ b/charts/trek/values.yaml @@ -134,7 +134,11 @@ persistence: existingClaim: "" annotations: {} -# Readiness and liveness probes +# Readiness and liveness probes. Overrides are merged over these defaults, so a key you +# do not set stays as shipped: --set probes.liveness.initialDelaySeconds=60 keeps the +# httpGet handler. Switching handler means clearing the old one in the same override +# (httpGet: null together with tcpSocket), otherwise the API rejects the pod with +# "may not specify more than 1 handler type". Set probes.liveness to null to drop a probe. probes: liveness: httpGet: diff --git a/wiki/Install-Helm.md b/wiki/Install-Helm.md index 4e447b22d..1e253b6da 100644 --- a/wiki/Install-Helm.md +++ b/wiki/Install-Helm.md @@ -169,6 +169,18 @@ resources: memory: 512Mi ``` +### Health Probes + +Liveness and readiness probes are configurable under `probes`. The defaults hit `/api/health` on port 3000 and match what the chart shipped before, so an existing install renders the same manifest. + +```bash +helm install trek trek/trek --set probes.liveness.initialDelaySeconds=60 --set probes.readiness.periodSeconds=20 +``` + +Raise `initialDelaySeconds` on slow storage or after a large migration, where the first start can outlast the default and leave the pod restarting in a loop. Overrides are merged over the defaults, so setting one key keeps the rest. To switch a probe to `exec` or `tcpSocket`, clear the shipped handler in the same override (`--set probes.liveness.httpGet=null`), otherwise Kubernetes rejects the pod with "may not specify more than 1 handler type". Set `probes.liveness=null` to drop a probe entirely. + +If you change `env.PORT`, update `service.port` and `probes.*.httpGet.port` to match. + ### Ingress ```yaml