diff --git a/docs/postgresql.md b/docs/postgresql.md index a1f6eb0..169603b 100644 --- a/docs/postgresql.md +++ b/docs/postgresql.md @@ -39,6 +39,38 @@ it is safe to re-run: existing roles and databases are left untouched. The postgres values must be specified for `authentik` and `openwebui`. They may use the same server, but should have different roles and databases. +## Passwords + +The openwebui postgres password is read from a Kubernetes `Secret`, under the key `password`. +The chart does not create it. Simply specify the resource name: + +```yaml +openwebui: + postgres: + passwordSecret: + name: vllm-openwebui-pg +``` + +For the Authentik subchart to also use an external secret, the password must be injected via `global.env`, which covers server and worker at +once: + +```yaml +authentik: + authentik: + postgresql: + password: # unset on purpose, supplied below + global: + env: + - name: AUTHENTIK_POSTGRESQL__PASSWORD + valueFrom: + secretKeyRef: { name: vllm-authentik-pg, key: password } +``` + +> [!IMPORTANT] +> +> Use alphanumeric passwords. OpenWebUI's is interpolated into a connection URI in the pod, +> where nothing percent-encodes it, so `@ : / ? # %` would corrupt the DSN. + ## Sharing a server between releases The names default to `vllm-openwebui` and `vllm-authentik`, if multiple diff --git a/templates/NOTES.txt b/templates/NOTES.txt index 128a5ac..7106f0c 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -2,3 +2,9 @@ VLLM Gateway and models have been successfully deployed on your cluster. You can access the gateway at https://gateway.{{ .Values.envoy.baseDomain }}/v1/chat/completions You can access Open-WebUI at https://openwebui.{{ .Values.envoy.baseDomain }}/ +{{- /* The subchart defaults it to "-postgresql", a plausible name that resolves +to nothing, so an omission would otherwise surface as an authentik CrashLoopBackOff. +*/}} +{{- if .Values.authentik.enabled }} + {{- $_ := .Values.authentik.authentik.postgresql.host | required ".Values.authentik.authentik.postgresql.host is required: the chart does not deploy PostgreSQL" }} +{{- end }} diff --git a/templates/openwebui/deployment.yaml b/templates/openwebui/deployment.yaml index a2fc638..f472915 100644 --- a/templates/openwebui/deployment.yaml +++ b/templates/openwebui/deployment.yaml @@ -34,11 +34,19 @@ spec: value: "true" - name: OPENAI_API_BASE_URL value: https://gateway.{{ .Values.envoy.baseDomain }}/v1 - - name: DATABASE_URL + {{- $pg := .Values.openwebui.postgres }} + {{- /* Must precede DATABASE_URL: $(VAR) only expands earlier entries. */}} + - name: PG_PASSWORD valueFrom: secretKeyRef: - name: {{ include "openwebui.fullname" . }}-postgres - key: OPENWEBUI_DATABASE_URL + name: {{ (default dict $pg.passwordSecret).name | required ".Values.openwebui.postgres.passwordSecret.name is required" }} + key: password + {{- /* One value fills both db and role. Guarded: an explicit null or "" deletes the + chart default, and an unset part of a DSN fails at connect time, not render time. */}} + {{- $db := $pg.database | required ".Values.openwebui.postgres.database is required" }} + {{- $ssl := $pg.sslMode | required ".Values.openwebui.postgres.sslMode is required" }} + - name: DATABASE_URL + value: "postgresql://{{ $db }}:$(PG_PASSWORD)@{{ $pg.host | required ".Values.openwebui.postgres.host is required" }}:5432/{{ $db }}?sslmode={{ $ssl }}" - name: ENABLE_OAUTH_SIGNUP value: "true" - name: ENABLE_LOGIN_FORM diff --git a/templates/postgres_secret.yaml b/templates/postgres_secret.yaml deleted file mode 100644 index 219fc6c..0000000 --- a/templates/postgres_secret.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.authentik.enabled }} - {{- /* The subchart defaults this to "-postgresql", which will not resolve. */}} - {{- $_ := .Values.authentik.authentik.postgresql.host | required ".Values.authentik.authentik.postgresql.host is required: the chart does not deploy PostgreSQL" }} -{{- end }} -{{- if .Values.openwebui.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: "{{ include "openwebui.fullname" . }}-postgres" -type: Opaque - {{- $pg := .Values.openwebui.postgres }} - {{- /* One value fills both db and role. */}} - {{- $db := $pg.database | required ".Values.openwebui.postgres.database is required" }} - {{- $host := $pg.host | required ".Values.openwebui.postgres.host is required" }} - {{- $password := $pg.password | required ".Values.openwebui.postgres.password is required" }} -stringData: - OPENWEBUI_DATABASE_URL: "postgresql://{{ $db }}:{{ $password }}@{{ $host }}:5432/{{ $db }}?sslmode={{ $pg.sslMode }}" -{{- end }} diff --git a/tools/helm/lint-values.yaml b/tools/helm/lint-values.yaml index 6f3f8ed..cd22008 100644 --- a/tools/helm/lint-values.yaml +++ b/tools/helm/lint-values.yaml @@ -14,7 +14,8 @@ openwebui: password: dummy postgres: host: pg.example.invalid - password: dummy + passwordSecret: + name: dummy-pg models: lint: &model fullName: org/lint-model diff --git a/values.yaml b/values.yaml index 7644f0f..d891bf3 100644 --- a/values.yaml +++ b/values.yaml @@ -62,7 +62,9 @@ openwebui: database: vllm-openwebui # "disable" puts every query on the wire in cleartext. sslMode: require - password: + # Existing secret holding the role's password under the key "password". + passwordSecret: + name: admin: user: admin email: admin@sdsc.ethz.ch