diff --git a/packages/twenty-docker/helm/twenty/templates/_helpers.tpl b/packages/twenty-docker/helm/twenty/templates/_helpers.tpl index 6f9d9534b3..661fb67c25 100644 --- a/packages/twenty-docker/helm/twenty/templates/_helpers.tpl +++ b/packages/twenty-docker/helm/twenty/templates/_helpers.tpl @@ -42,25 +42,50 @@ {{- regexFind "\\|(.+)$" . | trimPrefix "|" -}} {{- end -}} -{{/* Compose DB connection URL */}} -{{- define "twenty.dbUrl" -}} -{{- if .Values.server.env.PG_DATABASE_URL -}} -{{- .Values.server.env.PG_DATABASE_URL -}} -{{- else if .Values.db.enabled -}} -{{- $host := printf "%s-db" (include "twenty.fullname" .) -}} -{{- $user := .Values.db.internal.appUser | default "twenty_app_user" -}} -{{- $pass := .Values.db.internal.appPassword | default (randAlphaNum 32) -}} -{{- $db := .Values.db.internal.database | default "twenty" -}} -{{- printf "postgres://%s:%s@%s.%s.svc.cluster.local/%s" $user $pass $host (include "twenty.namespace" .) $db -}} +{{/* Check if using external secret for database password */}} +{{- define "twenty.db.useExternalSecret" -}} +{{- if and (not .Values.db.enabled) .Values.db.external.secretName .Values.db.external.passwordKey -}} +true {{- else -}} +false +{{- end -}} +{{- end -}} + +{{/* Database URL secret name */}} +{{- define "twenty.dbUrl.secretName" -}} +{{- printf "%s-db-url" (include "twenty.fullname" .) -}} +{{- end -}} + +{{/* Database password secret name */}} +{{- define "twenty.dbPassword.secretName" -}} +{{- if eq (include "twenty.db.useExternalSecret" .) "true" -}} +{{- .Values.db.external.secretName -}} +{{- else -}} +{{- include "twenty.dbUrl.secretName" . -}} +{{- end -}} +{{- end -}} + +{{/* Database password secret key */}} +{{- define "twenty.dbPassword.secretKey" -}} +{{- if eq (include "twenty.db.useExternalSecret" .) "true" -}} +{{- .Values.db.external.passwordKey -}} +{{- else if .Values.db.enabled -}} +appPassword +{{- else -}} +password +{{- end -}} +{{- end -}} + +{{/* Database URL template for external secret (will be evaluated at runtime) */}} +{{- define "twenty.dbUrl.template" -}} +{{- if eq (include "twenty.db.useExternalSecret" .) "true" -}} {{- $scheme := "postgres" -}} {{- $host := .Values.db.external.host -}} {{- $port := .Values.db.external.port | default 5432 -}} {{- $user := .Values.db.external.user | default "postgres" -}} -{{- $pass := .Values.db.external.password | default "postgres" -}} {{- $db := .Values.db.external.database | default "twenty" -}} {{- $qs := ternary "?sslmode=require" "" (eq .Values.db.external.ssl true) -}} -{{- printf "%s://%s:%s@%s:%v/%s%s" $scheme $user $pass $host $port $db $qs -}} +{{- printf "%s://%s:$(DB_PASSWORD)@%s:%v/%s%s" $scheme $user $host $port $db $qs -}} {{- end -}} {{- end -}} @@ -78,9 +103,11 @@ {{- end -}} {{- end -}} -{{/* Compose Server URL from ingress, else service */}} +{{/* Compose Server URL from override, ingress, or service */}} {{- define "twenty.serverUrl" -}} -{{- if and .Values.server.ingress.enabled (gt (len .Values.server.ingress.hosts) 0) -}} +{{- if .Values.server.env.SERVER_URL -}} +{{- .Values.server.env.SERVER_URL -}} +{{- else if and .Values.server.ingress.enabled (gt (len .Values.server.ingress.hosts) 0) -}} {{- $host := (index .Values.server.ingress.hosts 0).host -}} {{- $tls := gt (len .Values.server.ingress.tls) 0 -}} {{- $scheme := ternary "https" "http" $tls -}} diff --git a/packages/twenty-docker/helm/twenty/templates/deployment-server.yaml b/packages/twenty-docker/helm/twenty/templates/deployment-server.yaml index cb9764cd88..d2b4f15471 100644 --- a/packages/twenty-docker/helm/twenty/templates/deployment-server.yaml +++ b/packages/twenty-docker/helm/twenty/templates/deployment-server.yaml @@ -116,11 +116,21 @@ spec: - >- npx -y typeorm migration:run -d dist/database/typeorm/core/core.datasource env: + {{- if eq (include "twenty.db.useExternalSecret" .) "true" }} + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "twenty.dbPassword.secretName" . }} + key: {{ include "twenty.dbPassword.secretKey" . }} + - name: PG_DATABASE_URL + value: {{ include "twenty.dbUrl.template" . | quote }} + {{- else }} - name: PG_DATABASE_URL valueFrom: secretKeyRef: - name: {{ include "twenty.fullname" . }}-db-url + name: {{ include "twenty.dbUrl.secretName" . }} key: url + {{- end }} containers: - name: server {{- $img := include "twenty.server.image" . }} @@ -129,11 +139,21 @@ spec: env: - name: SERVER_URL value: {{ include "twenty.serverUrl" . | quote }} + {{- if eq (include "twenty.db.useExternalSecret" .) "true" }} + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "twenty.dbPassword.secretName" . }} + key: {{ include "twenty.dbPassword.secretKey" . }} + - name: PG_DATABASE_URL + value: {{ include "twenty.dbUrl.template" . | quote }} + {{- else }} - name: PG_DATABASE_URL valueFrom: secretKeyRef: - name: {{ include "twenty.fullname" . }}-db-url + name: {{ include "twenty.dbUrl.secretName" . }} key: url + {{- end }} - name: REDIS_URL value: {{ include "twenty.redisUrl" . | quote }} - name: SIGN_IN_PREFILLED diff --git a/packages/twenty-docker/helm/twenty/templates/deployment-worker.yaml b/packages/twenty-docker/helm/twenty/templates/deployment-worker.yaml index 2d8ad94674..dc47d13a08 100644 --- a/packages/twenty-docker/helm/twenty/templates/deployment-worker.yaml +++ b/packages/twenty-docker/helm/twenty/templates/deployment-worker.yaml @@ -52,11 +52,21 @@ spec: env: - name: SERVER_URL value: {{ include "twenty.serverUrl" . | quote }} + {{- if eq (include "twenty.db.useExternalSecret" .) "true" }} + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "twenty.dbPassword.secretName" . }} + key: {{ include "twenty.dbPassword.secretKey" . }} + - name: PG_DATABASE_URL + value: {{ include "twenty.dbUrl.template" . | quote }} + {{- else }} - name: PG_DATABASE_URL valueFrom: secretKeyRef: - name: {{ include "twenty.fullname" . }}-db-url + name: {{ include "twenty.dbUrl.secretName" . }} key: url + {{- end }} - name: REDIS_URL value: {{ include "twenty.redisUrl" . | quote }} - name: STORAGE_TYPE diff --git a/packages/twenty-docker/helm/twenty/templates/secret-db-url.yaml b/packages/twenty-docker/helm/twenty/templates/secret-db-url.yaml index 3bac0e1a1d..6f33fd2034 100644 --- a/packages/twenty-docker/helm/twenty/templates/secret-db-url.yaml +++ b/packages/twenty-docker/helm/twenty/templates/secret-db-url.yaml @@ -1,4 +1,5 @@ {{- $secretName := printf "%s-db-url" (include "twenty.fullname" .) -}} +{{- if .Values.db.enabled -}} {{- $existingSecret := lookup "v1" "Secret" (include "twenty.namespace" .) $secretName -}} {{- $appPassword := "" -}} {{- if $existingSecret -}} @@ -20,3 +21,25 @@ type: Opaque stringData: url: {{ printf "postgres://%s:%s@%s-db.%s.svc.cluster.local/%s" (urlquery $appUser) (urlquery $appPassword) (include "twenty.fullname" .) (include "twenty.namespace" .) (.Values.db.internal.database | default "twenty") | quote }} appPassword: {{ $appPassword | quote }} +{{- else if not .Values.db.external.secretName -}} +{{- $scheme := "postgres" -}} +{{- $host := .Values.db.external.host -}} +{{- $port := .Values.db.external.port | default 5432 -}} +{{- $user := .Values.db.external.user | default "postgres" -}} +{{- $pass := .Values.db.external.password | default "" -}} +{{- $db := .Values.db.external.database | default "twenty" -}} +{{- $qs := ternary "?sslmode=require" "" (eq .Values.db.external.ssl true) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ include "twenty.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "twenty.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: server +type: Opaque +stringData: + url: {{ printf "%s://%s:%s@%s:%v/%s%s" $scheme (urlquery $user) (urlquery $pass) $host $port $db $qs | quote }} + password: {{ $pass | quote }} +{{- end -}} diff --git a/packages/twenty-docker/helm/twenty/values.schema.json b/packages/twenty-docker/helm/twenty/values.schema.json index cd87ec264f..523042bfab 100644 --- a/packages/twenty-docker/helm/twenty/values.schema.json +++ b/packages/twenty-docker/helm/twenty/values.schema.json @@ -45,6 +45,7 @@ "env": { "type": "object", "properties": { + "SERVER_URL": { "type": "string", "description": "Override for the server URL (e.g., https://crm.example.com). If not set, derived from ingress or service." }, "NODE_PORT": { "type": "integer", "minimum": 1 }, "PG_DATABASE_URL": { "type": "string" }, "REDIS_URL": { "type": "string" }, diff --git a/packages/twenty-docker/helm/twenty/values.yaml b/packages/twenty-docker/helm/twenty/values.yaml index 657a224fa9..c9e7623997 100644 --- a/packages/twenty-docker/helm/twenty/values.yaml +++ b/packages/twenty-docker/helm/twenty/values.yaml @@ -19,8 +19,13 @@ storage: bucket: "" region: "" endpoint: "" + # Option A: direct values accessKeyId: "" secretAccessKey: "" + # Option B: reference a Secret + # secretName: my-s3-creds + # accessKeyIdKey: accessKeyId + # secretAccessKeyKey: secretAccessKey # Auth tokens (random if not provided) secrets: @@ -137,6 +142,8 @@ db: password: "" database: twenty ssl: false + secretName: "" + passwordKey: "" # Redis redisInternal: