From f0b0dd3e36d4ed703521b705c263933523acdb40 Mon Sep 17 00:00:00 2001 From: Maarten de Waard Date: Thu, 30 Sep 2021 14:37:30 +0200 Subject: [PATCH] add bitnami/Discourse chart as a basis, edit Chart.yaml --- deployment/helmchart/.helmignore | 23 + deployment/helmchart/Chart.yaml | 24 + deployment/helmchart/templates/NOTES.txt | 165 ++++ deployment/helmchart/templates/_helpers.tpl | 249 +++++++ .../helmchart/templates/configmaps.yaml | 50 ++ .../helmchart/templates/deployment.yaml | 275 +++++++ deployment/helmchart/templates/ingress.yaml | 55 ++ deployment/helmchart/templates/pvc.yaml | 23 + .../helmchart/templates/secrets-database.yaml | 17 + .../templates/secrets-discourse.yaml | 23 + .../helmchart/templates/secrets-redis.yaml | 16 + deployment/helmchart/templates/service.yaml | 42 ++ .../helmchart/templates/serviceaccount.yaml | 19 + .../helmchart/templates/tls-secrets.yaml | 19 + deployment/helmchart/values.yaml | 702 ++++++++++++++++++ 15 files changed, 1702 insertions(+) create mode 100644 deployment/helmchart/.helmignore create mode 100644 deployment/helmchart/Chart.yaml create mode 100644 deployment/helmchart/templates/NOTES.txt create mode 100644 deployment/helmchart/templates/_helpers.tpl create mode 100644 deployment/helmchart/templates/configmaps.yaml create mode 100644 deployment/helmchart/templates/deployment.yaml create mode 100644 deployment/helmchart/templates/ingress.yaml create mode 100644 deployment/helmchart/templates/pvc.yaml create mode 100644 deployment/helmchart/templates/secrets-database.yaml create mode 100644 deployment/helmchart/templates/secrets-discourse.yaml create mode 100644 deployment/helmchart/templates/secrets-redis.yaml create mode 100644 deployment/helmchart/templates/service.yaml create mode 100644 deployment/helmchart/templates/serviceaccount.yaml create mode 100644 deployment/helmchart/templates/tls-secrets.yaml create mode 100644 deployment/helmchart/values.yaml diff --git a/deployment/helmchart/.helmignore b/deployment/helmchart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/deployment/helmchart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/deployment/helmchart/Chart.yaml b/deployment/helmchart/Chart.yaml new file mode 100644 index 0000000..74c365d --- /dev/null +++ b/deployment/helmchart/Chart.yaml @@ -0,0 +1,24 @@ +annotations: + category: Dashboard +apiVersion: v2 +appVersion: 0.1.0 +dependencies: + - name: common + repository: https://charts.bitnami.com/bitnami + tags: + - bitnami-common + version: 1.x.x +description: A Helm chart for deploying the Stackspin Dashboard to Kubernetes +engine: gotpl +home: https://open.greenhost.net/openappstack/admin-frontend/ +icon: https://open.greenhost.net/openappstack/admin-frontend/-/blob/master/public/assets/logo.svg +keywords: + - stackspin + - dashboard +maintainers: + - email: info@openappstack.net + name: Stackspin +name: admin-frontend +sources: + - https://open.greenhost.net/openappstack/admin-frontend/ +version: 0.1.0 diff --git a/deployment/helmchart/templates/NOTES.txt b/deployment/helmchart/templates/NOTES.txt new file mode 100644 index 0000000..8caea61 --- /dev/null +++ b/deployment/helmchart/templates/NOTES.txt @@ -0,0 +1,165 @@ +{{- $secretName := include "discourse.secretName" . -}} +{{- $postgresqlSecretName := include "discourse.postgresql.secretName" . -}} +{{- $redisSecretName := include "discourse.redis.secretName" . -}} + +{{- if or .Values.postgresql.enabled .Values.externalDatabase.host -}} + +{{- if empty (include "discourse.host" .) -}} +############################################################################### +### ERROR: You did not provide an external host in your 'helm install' call ### +############################################################################### + +This deployment will be incomplete until you configure Discourse with a resolvable host. To configure Discourse with the URL of your service: + +1. Get the discourse URL by running: + + {{- if contains "NodePort" .Values.service.type }} + export DISCOURSE_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}"):$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} -o jsonpath="{.spec.ports[0].nodePort}") + {{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export DISCOURSE_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + {{- end }} + {{ include "common.utils.secret.getvalue" (dict "secret" $secretName "field" "discourse-password" "context" $) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $postgresqlSecretName "field" "postgresql-password" "context" $) }} + {{- if (include "discourse.redis.auth.enabled" .) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $redisSecretName "field" "redis-password" "context" $) }} + {{- end }} + +2. Complete your Discourse deployment by running: + +{{- if .Values.postgresql.enabled }} + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} bitnami/{{ .Chart.Name }} \ + --set discourse.host=$DISCOURSE_HOST \ + --set discourse.password=$DISCOURSE_PASSWORD \ + {{- if .Values.global }}{{- if .Values.global.imagePullSecrets }} + --set global.imagePullSecrets={{ .Values.global.imagePullSecrets }} \ + {{- end }}{{- end }} + {{- if and .Values.redis.enabled .Values.redis.auth.enabled (not .Values.redis.auth.existingSecret) (not .Values.redis.auth.password) }} + --set redis.auth.password=$REDIS_PASSWORD \ + {{- end }} + --set postgresql.postgresqlPassword=$POSTGRESQL_PASSWORD + +{{- else }} + + ## PLEASE UPDATE THE EXTERNAL DATABASE CONNECTION PARAMETERS IN THE FOLLOWING COMMAND AS NEEDED ## + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} bitnami/{{ .Chart.Name }} \ + --set discourse.host=$DISCOURSE_HOST \ + --set discourse.password=$DISCOURSE_PASSWORD \ + --set service.type={{ .Values.service.type }} \ + --set externalDatabase.host={{ .Values.externalDatabase.host }} \ + --set externalDatabase.port={{ .Values.externalDatabase.port }} \ + --set externalDatabase.user={{ .Values.externalDatabase.user }} \ + --set externalDatabase.password=$POSTGRESQL_PASSWORD \ + --set externalDatabase.database={{ .Values.externalDatabase.database }} \ + {{- if .Values.global }}{{- if .Values.global.imagePullSecrets }} + --set global.imagePullSecrets={{ .Values.global.imagePullSecrets }} \ + {{- end }}{{- end }} + {{- if and .Values.redis.enabled .Values.redis.auth.enabled (not .Values.redis.auth.existingSecret) (not .Values.redis.auth.password) }} + --set redis.auth.password=$REDIS_PASSWORD \ + {{- end }} + --set postgresql.enabled=false +{{- end }} + +{{- else -}} + +1. Get the Discourse URL by running: + + Discourse URL : http://{{ include "discourse.host" . }}/ + +{{- if eq .Values.service.type "ClusterIP" }} + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "common.names.fullname" . }} 80:{{ .Values.service.port }} +{{- end }} + +2. Get your Discourse login credentials by running: + + Username: {{ .Values.discourse.username }} + {{ include "common.utils.secret.getvalue" (dict "secret" $secretName "field" "discourse-password" "context" $) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $postgresqlSecretName "field" "postgresql-password" "context" $) }} + {{- if (include "discourse.redis.auth.enabled" .) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $redisSecretName "field" "redis-password" "context" $) }} + {{- end }} + +{{- end }} + +{{- else -}} + +######################################################################################## +### ERROR: You did not provide an external database host in your 'helm install' call ### +######################################################################################## + +This deployment will be incomplete until you configure Discourse with a resolvable database host. To configure Discourse to use and external database host: + +1. Complete your Discourse deployment by running: + +{{- if contains "NodePort" .Values.service.type }} + export DISCOURSE_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}"):$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} -o jsonpath="{.spec.ports[0].nodePort}") +{{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export DISCOURSE_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") +{{- else }} + + export DISCOURSE_HOST=127.0.0.1 +{{- end }} + {{ include "common.utils.secret.getvalue" (dict "secret" $secretName "field" "discourse-password" "context" $) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $postgresqlSecretName "field" "postgresql-password" "context" $) }} + {{- if (include "discourse.redis.auth.enabled" .) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $redisSecretName "field" "redis-password" "context" $) }} + {{- end }} + + + ## PLEASE UPDATE THE EXTERNAL DATABASE CONNECTION PARAMETERS IN THE FOLLOWING COMMAND AS NEEDED ## + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} bitnami/{{ .Chart.Name }} \ + --set discourse.host=$DISCOURSE_HOST \ + --set discourse.password=$DISCOURSE_PASSWORD \ + --set postgresql.enabled=false \ + {{- if not (empty .Values.externalDatabase.user) }} + --set externalDatabase.user={{ .Values.externalDatabase.user }} \ + {{- end }} + {{- if not (empty .Values.externalDatabase.password) }} + --set externalDatabase.password=$POSTGRESQL_PASSWORD \ + {{- end }} + {{- if not (empty .Values.externalDatabase.database) }} + --set externalDatabase.database={{ .Values.externalDatabase.database }} + {{- end }} + --set externalDatabase.host=YOUR_EXTERNAL_DATABASE_HOST \ + {{- if .Values.global }}{{- if .Values.global.imagePullSecrets }} + --set global.imagePullSecrets={{ .Values.global.imagePullSecrets }} \ + {{- end }}{{- end }} + {{- if and .Values.redis.enabled .Values.redis.auth.enabled (not .Values.redis.auth.existingSecret) (not .Values.redis.auth.password) }} + --set redis.auth.password=$REDIS_PASSWORD \ + {{- end }} + --set service.type={{ .Values.service.type }} +{{- end }} + +{{ if and .Values.postgresql.enabled (not .Values.postgresql.existingSecret) (eq .Values.postgresql.postgresqlPostgresPassword "bitnami") -}} +##################################################################################### +### WARNING: You did not change the default password for the PostgreSQL root user ### +##################################################################################### +{{- end }} + +{{- include "common.warnings.rollingTag" .Values.image }} + +{{- $passwordValidationErrors := list -}} +{{- if not .Values.discourse.existingSecret -}} + {{- $requiredDiscoursePassword := dict "valueKey" "discourse.password" "secret" $secretName "field" "discourse-password" "context" $ -}} + {{- $requiredDiscoursePasswordError := include "common.validations.values.single.empty" $requiredDiscoursePassword -}} + {{- $passwordValidationErrors = append $passwordValidationErrors $requiredDiscoursePasswordError -}} +{{- end -}} + +{{- $postgresqlPasswordValidationErrors := include "common.validations.values.postgresql.passwords" (dict "secret" $postgresqlSecretName "subchart" true "context" $) -}} +{{- $passwordValidationErrors = append $passwordValidationErrors $postgresqlPasswordValidationErrors -}} + +{{- if (include "discourse.redis.auth.enabled" .) }} +{{- $redisPasswordValidationErrors := include "common.validations.values.redis.passwords" (dict "secret" $redisSecretName "subchart" true "context" $) -}} +{{- $passwordValidationErrors = append $passwordValidationErrors $redisPasswordValidationErrors -}} +{{- end }} + +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $) -}} diff --git a/deployment/helmchart/templates/_helpers.tpl b/deployment/helmchart/templates/_helpers.tpl new file mode 100644 index 0000000..9bc649d --- /dev/null +++ b/deployment/helmchart/templates/_helpers.tpl @@ -0,0 +1,249 @@ + +{{/* +Create a default fully qualified app name +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.fullname" -}} +{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "redis.fullname" -}} +{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "discourse.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker image registry secret names +*/}} +{{- define "discourse.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Return true if a secret object for Discourse should be created +*/}} +{{- define "discourse.createSecret" -}} +{{- if or (not .Values.discourse.existingSecret) (and (not .Values.discourse.smtp.existingSecret) .Values.discourse.smtp.password .Values.discourse.smtp.enabled) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Discourse secret name +*/}} +{{- define "discourse.secretName" -}} +{{- if .Values.discourse.existingSecret }} + {{- printf "%s" .Values.discourse.existingSecret -}} +{{- else -}} + {{- printf "%s-discourse" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Discourse SMTP secret name +*/}} +{{- define "discourse.smtp.secretName" -}} +{{- if .Values.discourse.smtp.existingSecret }} + {{- printf "%s" .Values.discourse.smtp.existingSecret -}} +{{- else -}} + {{- printf "%s-discourse" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if Discourse SMTP uses password authentication +*/}} +{{- define "discourse.smtp.password.enabled" -}} +{{- if and (or .Values.discourse.smtp.password .Values.discourse.smtp.existingSecret) .Values.discourse.smtp.enabled }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the user defined LoadBalancerIP for this release +Note, returns 127.0.0.1 if using ClusterIP. +*/}} +{{- define "discourse.serviceIP" -}} +{{- if eq .Values.service.type "ClusterIP" -}} +127.0.0.1 +{{- else -}} +{{- .Values.service.loadBalancerIP | default "" -}} +{{- end -}} +{{- end -}} + +{{/* +Gets the host to be used for this application. +If not using ClusterIP, or if a host or LoadBalancerIP is not defined, the value will be empty +*/}} +{{- define "discourse.host" -}} +{{- $host := .Values.discourse.host | default "" -}} +{{- default (include "discourse.serviceIP" .) $host -}} +{{- end -}} + +{{/* +Return the proper Discourse image name +*/}} +{{- define "discourse.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Storage Class +*/}} +{{- define "discourse.storageClass" -}} +{{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) -}} +{{- end -}} + +{{/* +Return the Postgresql hostname +*/}} +{{- define "discourse.databaseHost" -}} +{{- if .Values.postgresql.enabled }} + {{- printf "%s" (include "postgresql.fullname" .) -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.host -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Postgresql port +*/}} +{{- define "discourse.databasePort" -}} +{{- if .Values.postgresql.enabled }} + {{- printf "5432" | quote -}} +{{- else -}} + {{- .Values.externalDatabase.port | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Postgresql database name +*/}} +{{- define "discourse.databaseName" -}} +{{- if .Values.postgresql.enabled }} + {{- printf "%s" .Values.postgresql.postgresqlDatabase -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.database -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Postgresql user +*/}} +{{- define "discourse.databaseUser" -}} +{{- if .Values.postgresql.enabled }} + {{- printf "%s" .Values.postgresql.postgresqlUsername -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.user -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object for Postgres should be created +*/}} +{{- define "discourse.postgresql.createSecret" -}} +{{- if and (not .Values.postgresql.enabled) (not .Values.externalDatabase.existingSecret) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Postgresql secret name +*/}} +{{- define "discourse.postgresql.secretName" -}} +{{- if .Values.postgresql.enabled }} + {{- if .Values.postgresql.existingSecret }} + {{- printf "%s" .Values.postgresql.existingSecret -}} + {{- else -}} + {{- printf "%s" (include "postgresql.fullname" .) -}} + {{- end -}} +{{- else if .Values.externalDatabase.existingSecret }} + {{- printf "%s" .Values.externalDatabase.existingSecret -}} +{{- else -}} + {{- printf "%s-database" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Redis™ hostname +*/}} +{{- define "discourse.redisHost" -}} +{{- if .Values.redis.enabled }} + {{- printf "%s-master" (include "redis.fullname" .) -}} +{{- else -}} + {{- printf "%s" .Values.externalRedis.host -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Redis™ port +*/}} +{{- define "discourse.redisPort" -}} +{{- if .Values.redis.enabled }} + {{- printf "6379" | quote -}} +{{- else -}} + {{- .Values.externalRedis.port | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object for Redis™ should be created +*/}} +{{- define "discourse.redis.createSecret" -}} +{{- if and (not .Values.redis.enabled) (not .Values.externalRedis.existingSecret) .Values.externalRedis.password }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Redis™ secret name +*/}} +{{- define "discourse.redis.secretName" -}} +{{- if .Values.redis.enabled }} + {{- if .Values.redis.auth.existingSecret }} + {{- printf "%s" .Values.redis.auth.existingSecret -}} + {{- else -}} + {{- printf "%s" (include "redis.fullname" .) -}} + {{- end -}} +{{- else if .Values.externalRedis.existingSecret }} + {{- printf "%s" .Values.externalRedis.existingSecret -}} +{{- else -}} + {{- printf "%s-redis" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the Redis™ secret key +*/}} +{{- define "discourse.redis.secretPasswordKey" -}} +{{- if and .Values.redis.enabled .Values.redis.auth.existingSecret }} + {{- required "You need to provide existingSecretPasswordKey when an existingSecret is specified in redis" .Values.redis.auth.existingSecretPasswordKey | printf "%s" }} +{{- else if and (not .Values.redis.enabled) .Values.externalRedis.existingSecret }} + {{- required "You need to provide existingSecretPasswordKey when an existingSecret is specified in redis" .Values.externalRedis.existingSecretPasswordKey | printf "%s" }} +{{- else -}} + {{- printf "redis-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Return whether Redis™ uses password authentication or not +*/}} +{{- define "discourse.redis.auth.enabled" -}} +{{- if or (and .Values.redis.enabled .Values.redis.auth.enabled) (and (not .Values.redis.enabled) (or .Values.externalRedis.password .Values.externalRedis.existingSecret)) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/deployment/helmchart/templates/configmaps.yaml b/deployment/helmchart/templates/configmaps.yaml new file mode 100644 index 0000000..cded68d --- /dev/null +++ b/deployment/helmchart/templates/configmaps.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + {{- $port := .Values.service.port | toString }} + DISCOURSE_HOST: "{{ include "discourse.host" . }}" + DISCOURSE_SKIP_INSTALL: {{ ternary "yes" "no" .Values.discourse.skipInstall | quote }} + DISCOURSE_SITE_NAME: {{ .Values.discourse.siteName | quote }} + DISCOURSE_USERNAME: {{ .Values.discourse.username | quote }} + DISCOURSE_EMAIL: {{ .Values.discourse.email | quote }} + DISCOURSE_REDIS_HOST: {{ template "discourse.redisHost" . }} + DISCOURSE_REDIS_PORT_NUMBER: {{ template "discourse.redisPort" . }} + DISCOURSE_DATABASE_HOST: {{ template "discourse.databaseHost" . }} + DISCOURSE_DATABASE_PORT_NUMBER: {{ template "discourse.databasePort" . }} + DISCOURSE_DATABASE_NAME: {{ template "discourse.databaseName" . }} + DISCOURSE_DATABASE_USER: {{ template "discourse.databaseUser" . }} + {{- if .Values.discourse.smtp.enabled }} + DISCOURSE_SMTP_HOST: {{ .Values.discourse.smtp.host | quote }} + DISCOURSE_SMTP_PORT: {{ .Values.discourse.smtp.port | quote }} + {{- if .Values.discourse.smtp.user }} + DISCOURSE_SMTP_USER: {{ .Values.discourse.smtp.user | quote }} + {{- end }} + {{- if .Values.discourse.smtp.protocol }} + DISCOURSE_SMTP_PROTOCOL: {{ .Values.discourse.smtp.protocol | quote }} + {{- end }} + {{- if .Values.discourse.smtp.auth }} + DISCOURSE_SMTP_AUTH: {{ .Values.discourse.smtp.auth | quote }} + {{- end }} + {{- end }} + {{- if or .Values.postgresql.enabled .Values.externalDatabase.create }} + POSTGRESQL_CLIENT_DATABASE_HOST: {{ template "discourse.databaseHost" . }} + POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER: {{ template "discourse.databasePort" . }} + {{- if or .Values.postgresql.enabled (not .Values.externalDatabase.postgresqlPostgresUser) }} + POSTGRESQL_CLIENT_POSTGRES_USER: "postgres" + {{- else }} + POSTGRESQL_CLIENT_POSTGRES_USER: {{ .Values.externalDatabase.postgresqlPostgresUser | quote }} + POSTGRESQL_CLIENT_CREATE_DATABASE_USERNAME: {{ .Values.externalDatabase.user | quote }} + POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD: {{ .Values.externalDatabase.password | quote }} + {{- end }} + POSTGRESQL_CLIENT_CREATE_DATABASE_NAME: {{ template "discourse.databaseName" . }} + POSTGRESQL_CLIENT_CREATE_DATABASE_EXTENSIONS: "hstore,pg_trgm" + {{- end }} diff --git a/deployment/helmchart/templates/deployment.yaml b/deployment/helmchart/templates/deployment.yaml new file mode 100644 index 0000000..7a94f21 --- /dev/null +++ b/deployment/helmchart/templates/deployment.yaml @@ -0,0 +1,275 @@ +{{- if and (include "discourse.host" .) (or .Values.postgresql.enabled .Values.externalDatabase.host) -}} +apiVersion: {{ template "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "common.names.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + component: discourse + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + component: discourse + {{- if .Values.updateStrategy }} + strategy: {{- toYaml .Values.updateStrategy | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmaps.yaml") . | sha256sum }} + checksum/secrets-discourse: {{ include (print $.Template.BasePath "/secrets-discourse.yaml") . | sha256sum }} + checksum/secrets-database: {{ include (print $.Template.BasePath "/secrets-database.yaml") . | sha256sum }} + checksum/secrets-redis: {{ include (print $.Template.BasePath "/secrets-redis.yaml") . | sha256sum }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + component: discourse + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.podAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + spec: + {{- include "discourse.imagePullSecrets" . | nindent 6 }} + {{- if .Values.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "discourse.serviceAccountName" . }} + securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} + initContainers: + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "discourse.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - sh + - -c + - | + mkdir -p "/bitnami/discourse" + chown -R "discourse:root" "/bitnami/discourse" + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: discourse-data + mountPath: /bitnami/discourse + {{- end }} + containers: + - name: discourse + securityContext: {{- toYaml .Values.discourse.containerSecurityContext | nindent 12 }} + image: {{ template "discourse.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.discourse.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.discourse.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.discourse.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.discourse.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: DISCOURSE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.secretName" . }} + key: discourse-password + - name: DISCOURSE_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.postgresql.secretName" . }} + key: postgresql-password + {{- if or .Values.postgresql.enabled .Values.externalDatabase.create }} + - name: POSTGRESQL_CLIENT_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.postgresql.secretName" . }} + key: postgresql-postgres-password + {{- end }} + {{- if (include "discourse.redis.auth.enabled" .) }} + - name: DISCOURSE_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.redis.secretName" . }} + key: {{ include "discourse.redis.secretPasswordKey" . }} + {{- end }} + {{- if (include "discourse.smtp.password.enabled" .) }} + - name: DISCOURSE_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.smtp.secretName" . }} + key: smtp-password + {{- end }} + {{- if .Values.discourse.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.discourse.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ include "common.names.fullname" . }} + {{- if .Values.discourse.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.discourse.extraEnvVarsCM }} + {{- end }} + {{- if .Values.discourse.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.discourse.extraEnvVarsSecret }} + {{- end }} + ports: + - name: http + containerPort: 3000 + protocol: TCP + {{- if .Values.discourse.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /srv/status + port: http + initialDelaySeconds: {{ .Values.discourse.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.discourse.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.discourse.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.discourse.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.discourse.livenessProbe.failureThreshold }} + {{- else if .Values.discourse.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.discourse.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.discourse.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /srv/status + port: http + initialDelaySeconds: {{ .Values.discourse.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.discourse.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.discourse.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.discourse.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.discourse.readinessProbe.failureThreshold }} + {{- else if .Values.discourse.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.discourse.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - name: discourse-data + mountPath: /bitnami/discourse + subPath: discourse + {{- if .Values.discourse.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.discourse.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.discourse.resources }} + resources: {{- toYaml .Values.discourse.resources | nindent 12 }} + {{- end }} + - name: sidekiq + securityContext: {{- toYaml .Values.sidekiq.containerSecurityContext | nindent 12 }} + image: {{ template "discourse.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.args "context" $) | nindent 12 }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: DISCOURSE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.secretName" . }} + key: discourse-password + - name: DISCOURSE_POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.postgresql.secretName" . }} + key: postgresql-password + {{- if (include "discourse.redis.auth.enabled" .) }} + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.redis.secretName" . }} + key: {{ include "discourse.redis.secretPasswordKey" . }} + {{- end }} + {{- if (include "discourse.smtp.password.enabled" .) }} + - name: DISCOURSE_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "discourse.smtp.secretName" . }} + key: smtp-password + {{- end }} + {{- if .Values.sidekiq.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ include "common.names.fullname" . }} + {{- if .Values.sidekiq.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.sidekiq.extraEnvVarsCM }} + {{- end }} + {{- if .Values.sidekiq.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.sidekiq.extraEnvVarsSecret }} + {{- end }} + {{- if .Values.sidekiq.livenessProbe.enabled }} + livenessProbe: + exec: + command: ["/bin/sh", "-c", "pgrep -f ^sidekiq"] + initialDelaySeconds: {{ .Values.sidekiq.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sidekiq.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sidekiq.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sidekiq.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.sidekiq.livenessProbe.failureThreshold }} + {{- else if .Values.sidekiq.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidekiq.readinessProbe.enabled }} + readinessProbe: + exec: + command: ["/bin/sh", "-c", "pgrep -f ^sidekiq"] + initialDelaySeconds: {{ .Values.sidekiq.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.sidekiq.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.sidekiq.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.sidekiq.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.sidekiq.readinessProbe.failureThreshold }} + {{- else if .Values.sidekiq.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - name: discourse-data + mountPath: /bitnami/discourse + subPath: discourse + {{- if .Values.sidekiq.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidekiq.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidekiq.resources }} + resources: {{- toYaml .Values.sidekiq.resources | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: discourse-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "common.names.fullname" .) }} + {{- else }} + emptyDir: {} + {{ end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/deployment/helmchart/templates/ingress.yaml b/deployment/helmchart/templates/ingress.yaml new file mode 100644 index 0000000..f266f58 --- /dev/null +++ b/deployment/helmchart/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: {{ template "common.capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "common.names.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.ingress.annotations .Values.ingress.certManager .Values.commonAnnotations }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.ingress.annotations }} + {{- toYaml .Values.ingress.annotations | nindent 4 }} + {{- end }} + {{- if .Values.ingress.certManager }} + kubernetes.io/tls-acme: "true" + {{- end }} + {{- end }} +spec: + {{- if or .Values.ingress.tls .Values.ingress.extraTls }} + tls: + {{- if .Values.ingress.tls }} + - hosts: + - {{ .Values.ingress.hostname }} + secretName: {{ printf "%s-tls" .Values.ingress.hostname }} + {{- end }} + {{- if .Values.ingress.extraTls }} + {{- toYaml .Values.ingress.extraTls | nindent 4 }} + {{- end }} + {{- end }} + rules: + {{- if .Values.ingress.hostname }} + - host: {{ .Values.ingress.hostname }} + http: + paths: + - path: {{ .Values.ingress.path }} + {{- if eq "true" (include "common.ingress.supportsPathType" .) }} + pathType: {{ .Values.ingress.pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- range .Values.ingress.extraHosts }} + - host: {{ .name }} + http: + paths: + - path: {{ default "/" .path }} + {{- if eq "true" (include "common.ingress.supportsPathType" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} +{{- end }} diff --git a/deployment/helmchart/templates/pvc.yaml b/deployment/helmchart/templates/pvc.yaml new file mode 100644 index 0000000..42e02c2 --- /dev/null +++ b/deployment/helmchart/templates/pvc.yaml @@ -0,0 +1,23 @@ +{{- if and (include "discourse.host" .) .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "common.names.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "discourse.storageClass" . }} + {{- if .Values.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.selector "context" $) | nindent 4 }} + {{- end -}} +{{- end }} diff --git a/deployment/helmchart/templates/secrets-database.yaml b/deployment/helmchart/templates/secrets-database.yaml new file mode 100644 index 0000000..d9f42f7 --- /dev/null +++ b/deployment/helmchart/templates/secrets-database.yaml @@ -0,0 +1,17 @@ +{{- if (include "discourse.postgresql.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }}-database + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + postgresql-password: {{ .Values.externalDatabase.password | b64enc | quote }} + postgresql-postgres-password: {{ .Values.externalDatabase.postgresqlPostgresPassword | b64enc | quote }} +{{- end }} diff --git a/deployment/helmchart/templates/secrets-discourse.yaml b/deployment/helmchart/templates/secrets-discourse.yaml new file mode 100644 index 0000000..5f81810 --- /dev/null +++ b/deployment/helmchart/templates/secrets-discourse.yaml @@ -0,0 +1,23 @@ +{{- if (include "discourse.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }}-discourse + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if and (.Values.discourse.password) (not .Values.discourse.existingSecret) }} + discourse-password: {{ .Values.discourse.password | b64enc | quote }} + {{- else if not .Values.discourse.existingSecret }} + discourse-password: {{ randAlphaNum 10 | b64enc | quote }} + {{- end }} + {{- if and (.Values.discourse.smtp.password) (.Values.discourse.smtp.enabled) (not .Values.discourse.smtp.existingSecret) }} + smtp-password: {{ .Values.discourse.smtp.password | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/deployment/helmchart/templates/secrets-redis.yaml b/deployment/helmchart/templates/secrets-redis.yaml new file mode 100644 index 0000000..b854605 --- /dev/null +++ b/deployment/helmchart/templates/secrets-redis.yaml @@ -0,0 +1,16 @@ +{{- if (include "discourse.redis.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }}-redis + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + redis-password: {{ .Values.externalRedis.password | b64enc | quote }} +{{- end }} diff --git a/deployment/helmchart/templates/service.yaml b/deployment/helmchart/templates/service.yaml new file mode 100644 index 0000000..b196f32 --- /dev/null +++ b/deployment/helmchart/templates/service.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.service.annotations .Values.commonAnnotations}} + annotations: + {{- if .Values.service.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges) }} + loadBalancerSourceRanges: + {{ toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.service.port }} + targetPort: http + {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.http))) }} + nodePort: {{ .Values.service.nodePorts.http }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} diff --git a/deployment/helmchart/templates/serviceaccount.yaml b/deployment/helmchart/templates/serviceaccount.yaml new file mode 100644 index 0000000..acbe841 --- /dev/null +++ b/deployment/helmchart/templates/serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "discourse.serviceAccountName" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.serviceAccount.annotations }} + {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/deployment/helmchart/templates/tls-secrets.yaml b/deployment/helmchart/templates/tls-secrets.yaml new file mode 100644 index 0000000..090ce7c --- /dev/null +++ b/deployment/helmchart/templates/tls-secrets.yaml @@ -0,0 +1,19 @@ +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + labels: {{- include "common.labels.standard" $ | nindent 4 }} + {{- if $.Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .key | b64enc }} +{{- end }} +{{- end }} diff --git a/deployment/helmchart/values.yaml b/deployment/helmchart/values.yaml new file mode 100644 index 0000000..d5d25bd --- /dev/null +++ b/deployment/helmchart/values.yaml @@ -0,0 +1,702 @@ +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + +## @section Common parameters + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override discourse.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override discourse.fullname template +## +fullnameOverride: "" +## @param commonLabels Labels to be added to all deployed resources +## +commonLabels: {} +## @param commonAnnotations Annotations to be added to all deployed resources +## +commonAnnotations: {} + + +## @section Service parameters + +## Kubernetes service configuration. For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP +## +service: + ## @param service.type Kubernetes Service type + ## + type: LoadBalancer + ## @param service.port Service HTTP port + ## + port: 80 + ## @param service.nodePort Node Ports to expose + ## + nodePort: "" + ## @param service.loadBalancerIP Use loadBalancerIP to request a specific static IP + ## + loadBalancerIP: "" + ## @param service.externalTrafficPolicy Enable client source IP preservation + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.annotations Service annotations + ## + annotations: {} + ## @param service.loadBalancerSourceRanges Limits which cidr blocks can connect to service's load balancer + ## Only valid if service.type: LoadBalancer + ## + loadBalancerSourceRanges: [] + ## @param service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.nodePorts.http Kubernetes http node port + ## Example: + ## nodePorts: + ## http: + ## + nodePorts: + http: "" + +## @section Discourse parameters + +## Bitnami Discourse image version +## ref: https://hub.docker.com/r/bitnami/discourse/tags/ +## @param image.registry Discourse image registry +## @param image.repository Discourse image repository +## @param image.tag Discourse image tag +## @param image.pullPolicy Discourse image pull policy +## @param image.pullSecrets Discourse image pull secrets +## @param image.debug Specify if debug logs should be enabled +## +image: + registry: docker.io + repository: bitnami/discourse + tag: 2.7.8-debian-10-r22 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## + debug: false +## @param imagePullSecrets Specify docker-registry secret names as an array +## +imagePullSecrets: [] +## Discourse configuration parameters +## ref: https://github.com/bitnami/bitnami-docker-discourse#configuration +## +discourse: + ## @param discourse.host Discourse host to create application URLs (include the port if =/= 80) + ## + host: "" + ## @param discourse.siteName Discourse site name + ## + siteName: 'My Site!' + ## @param discourse.username Admin user of the application + ## + username: user + ## @param discourse.password password. WARNING: Minimum length of 10 characters + ## Defaults to a random 10-character alphanumeric string if not set + ## + password: "" + ## @param discourse.existingSecret Name of an existing secret containing the password (ignores previous password) + ## The secret should contain the following key: + ## discourse-password + ## + existingSecret: "" + ## @param discourse.email Admin user email of the application + ## + email: user@example.com + ## @param discourse.command Custom command to override image cmd + ## + command: [] + ## @param discourse.args Custom args for the custom command + ## + args: [] + ## @param discourse.containerSecurityContext Container security context specification + ## Example: + ## capabilities: + ## drop: + ## - ALL + ## readOnlyRootFilesystem: true + ## runAsNonRoot: true + ## runAsUser: 1000 + ## + containerSecurityContext: {} + ## Discourse container's resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param discourse.resources.limits The resources limits for the container + ## @param discourse.resources.requests The requested resources for the container + ## + resources: + ## Example: + ## limits: + ## cpu: 100m + ## memory: 128Mi + limits: {} + ## Examples: + ## requests: + ## cpu: 100m + ## memory: 128Mi + requests: {} + ## Discourse extra options for liveness probe + ## WARNING: Discourse installation process may take up some time and + ## setting inappropriate values here may lead to pods failure. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param discourse.livenessProbe.enabled Enable/disable livenessProbe + ## @param discourse.livenessProbe.initialDelaySeconds Delay before liveness probe is initiated + ## @param discourse.livenessProbe.periodSeconds How often to perform the probe + ## @param discourse.livenessProbe.timeoutSeconds When the probe times out + ## @param discourse.livenessProbe.failureThreshold Minimum consecutive failures for the probe + ## @param discourse.livenessProbe.successThreshold Minimum consecutive successes for the probe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 500 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## Discourse extra options for readiness probe + ## WARNING: Discourse installation process may take up some time and + ## setting inappropriate values here may lead to pods failure. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param discourse.readinessProbe.enabled Enable/disable readinessProbe + ## @param discourse.readinessProbe.initialDelaySeconds Delay before readiness probe is initiated + ## @param discourse.readinessProbe.periodSeconds How often to perform the probe + ## @param discourse.readinessProbe.timeoutSeconds When the probe times out + ## @param discourse.readinessProbe.failureThreshold Minimum consecutive failures for the probe + ## @param discourse.readinessProbe.successThreshold Minimum consecutive successes for the probe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param discourse.customLivenessProbe Custom liveness probe to execute (when the main one is disabled) + ## + customLivenessProbe: {} + ## @param discourse.customReadinessProbe Custom readiness probe to execute (when the main one is disabled) + ## + customReadinessProbe: {} + ## Discourse SMTP settings + ## @param discourse.smtp.enabled Enable/disable SMTP + ## @param discourse.smtp.host SMTP host name + ## @param discourse.smtp.port SMTP port number + ## @param discourse.smtp.user SMTP account user name + ## @param discourse.smtp.password SMTP account password + ## @param discourse.smtp.protocol SMTP protocol (Allowed values: tls, ssl) + ## @param discourse.smtp.auth SMTP authentication method + ## @param discourse.smtp.existingSecret Name of an existing Kubernetes secret. The secret must have the following key configured: `smtp-password` + ## + smtp: + enabled: false + host: "" + port: "" + user: "" + password: "" + protocol: "" + auth: "" + existingSecret: "" + ## @param discourse.extraEnvVars An array to add extra env vars + ## For example: + ## extraEnvVars: + ## discourse: + ## - name: DISCOURSE_ELASTICSEARCH_URL + ## value: test + ## + extraEnvVars: [] + ## @param discourse.extraEnvVarsCM Array to add extra configmaps + ## + extraEnvVarsCM: [] + ## @param discourse.extraEnvVarsSecret Array to add extra environment variables from a secret + ## + extraEnvVarsSecret: "" + ## @param discourse.extraVolumeMounts Additional volume mounts (used along with `extraVolumes`) + ## Example: Mount CA file + ## extraVolumeMounts + ## - name: ca-cert + ## subPath: ca_cert + ## mountPath: /path/to/ca_cert + ## + extraVolumeMounts: [] + ## @param discourse.skipInstall Do not run the Discourse installation wizard + ## Use only in case you are importing an existing database. + ## + skipInstall: false +## @param replicaCount Number of Discourse & Sidekiq replicas +## (Note that you will need ReadWriteMany PVCs for this to work properly) +## +replicaCount: 1 +## @param extraVolumes Array of extra volumes to be added deployment. Requires setting `extraVolumeMounts` +## Example: Add secret volume +## extraVolumes: +## - name: ca-cert +## secret: +## secretName: ca-cert +## items: +## - key: ca-cert +## path: ca_cert +## +extraVolumes: [] +## @param sidecars Attach additional sidecar containers to the pod +## Example: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @param initContainers Additional init containers to add to the pods +## +## e.g. +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +initContainers: [] +## @param serviceAccount.create Whether the service account should be created +## @param serviceAccount.annotations Annotations to add to the service account +## @param serviceAccount.name Name to be used for the service account +## +serviceAccount: + create: false + annotations: {} + ## If not set and create is true, a name is generated using the fullname template + ## + name: "" +## @param podSecurityContext Pod security context specification +## Example: +## fsGroup: 2000 +## +## +podSecurityContext: {} +## @param hostAliases Add deployment host aliases +## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: [] +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + ## @param persistence.enabled Whether to enable persistence based on Persistent Volume Claims + ## + enabled: true + ## @param persistence.storageClass discourse & sidekiq data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param persistence.existingClaim Use a existing PVC which must be created manually before bound + ## + existingClaim: "" + ## @param persistence.accessMode PVC Access Mode (RWO, ROX, RWX) + ## + accessMode: ReadWriteOnce + ## @param persistence.size Size of the PVC to request + ## + size: 10Gi + ## @param persistence.selector Selector to match an existing Persistent Volume (this value is evaluated as a template) + ## selector: + ## matchLabels: + ## app: my-app + selector: {} +## @param updateStrategy.type Update strategy type. Only really applicable for deployments with RWO PVs attached +## If replicas = 1, an update can get "stuck", as the previous pod remains attached to the +## PV, and the "incoming" pod can never start. Changing the strategy to "Recreate" will +## terminate the single previous pod, so that the new, incoming pod can attach to the PV +## Example: +## updateStrategy: +## type: RollingUpdate +## rollingUpdate: +## maxSurge: 25% +## maxUnavailable: 25% +updateStrategy: + type: RollingUpdate +## @param podAnnotations Additional pod annotations +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podLabels Additional pod labels +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAffinityPreset Pod affinity preset. Allowed values: soft, hard +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## @param nodeAffinityPreset.key Node label key to match Ignored if `affinity` is set. +## @param nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set. +## +nodeAffinityPreset: + type: "" + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment. +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +## @param tolerations Tolerations for pod assignment. +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +## @section Sidekiq parameters + +sidekiq: + ## @param sidekiq.containerSecurityContext Container security context specification + ## capabilities: + ## drop: + ## - ALL + ## readOnlyRootFilesystem: true + ## runAsNonRoot: true + ## runAsUser: 1000 + ## + containerSecurityContext: {} + ## @param sidekiq.command Custom command to override image cmd (evaluated as a template) + ## + command: ['/opt/bitnami/scripts/discourse/entrypoint.sh'] + ## @param sidekiq.args Custom args for the custom command (evaluated as a template) + ## + args: ['/opt/bitnami/scripts/discourse-sidekiq/run.sh'] + ## @param sidekiq.resources Sidekiq container resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## + resources: {} + ## Sidekiq extra options for liveness probe + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param sidekiq.livenessProbe.enabled Enable/disable livenessProbe + ## @param sidekiq.livenessProbe.initialDelaySeconds Delay before liveness probe is initiated + ## @param sidekiq.livenessProbe.periodSeconds How often to perform the probe + ## @param sidekiq.livenessProbe.timeoutSeconds When the probe times out + ## @param sidekiq.livenessProbe.failureThreshold Minimum consecutive failures for the probe + ## @param sidekiq.livenessProbe.successThreshold Minimum consecutive successes for the probe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 500 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## Sidekiq extra options for readiness probe + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param sidekiq.readinessProbe.enabled Enable/disable readinessProbe + ## @param sidekiq.readinessProbe.initialDelaySeconds Delay before readiness probe is initiated + ## @param sidekiq.readinessProbe.periodSeconds How often to perform the probe + ## @param sidekiq.readinessProbe.timeoutSeconds When the probe times out + ## @param sidekiq.readinessProbe.failureThreshold Minimum consecutive failures for the probe + ## @param sidekiq.readinessProbe.successThreshold Minimum consecutive successes for the probe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param sidekiq.customLivenessProbe Custom liveness probe to execute (when the main one is disabled) + ## + customLivenessProbe: {} + ## @param sidekiq.customReadinessProbe Custom readiness probe to execute (when the main one is disabled) + ## + customReadinessProbe: {} + ## @param sidekiq.extraEnvVars An array to add extra env vars + ## For example: + ## extraEnvVars: + ## - name: DISCOURSE_ELASTICSEARCH_URL + ## value: test + ## + extraEnvVars: [] + ## @param sidekiq.extraEnvVarsCM Array to add extra configmaps + ## + extraEnvVarsCM: [] + ## @param sidekiq.extraEnvVarsSecret Name of the secret that holds extra env vars + ## + extraEnvVarsSecret: "" + ## @param sidekiq.extraVolumeMounts Additional volume mounts + ## Example: Mount CA file + ## extraVolumeMounts + ## - name: ca-cert + ## subPath: ca_cert + ## mountPath: /path/to/ca_cert + ## + extraVolumeMounts: [] + +## @section Volume Permissions parameters + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup +## values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) + ## + enabled: false + ## Init containers' resource requests and limits + ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param volumePermissions.resources.limits The resources limits for the init container + ## @param volumePermissions.resources.requests The requested resources for the init container + ## + resources: + ## Example: + ## limits: + ## cpu: 100m + ## memory: 128Mi + limits: {} + ## Examples: + ## requests: + ## cpu: 100m + ## memory: 128Mi + requests: {} + +## @section Ingress parameters + +## Ingress parameters +## +ingress: + ## @param ingress.enabled Enable ingress controller resource + ## + enabled: false + ## @param ingress.certManager Add annotations for cert-manager + ## + certManager: false + ## @param ingress.hostname Default host for the ingress resource + ## + hostname: discourse.local + ## @param ingress.apiVersion Force Ingress API version (automatically detected if not set) + ## + apiVersion: "" + ## @param ingress.path Ingress path + ## + path: / + ## @param ingress.pathType Ingress path type + ## + pathType: ImplementationSpecific + ## @param ingress.annotations Ingress annotations done as key:value pairs + ## For a full list of possible ingress annotations, please see + ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md + ## + ## If certManager is set to true, annotation kubernetes.io/tls-acme: "true" will automatically be set + ## + annotations: {} + ## @param ingress.tls Enable TLS configuration for the hostname defined at ingress.hostname parameter + ## TLS certificates will be retrieved from a TLS secret with name: {{- printf "%s-tls" .Values.ingress.hostname }} + ## You can use the ingress.secrets parameter to create this TLS secret or relay on cert-manager to create it + ## + tls: false + ## @param ingress.extraHosts The list of additional hostnames to be covered with this ingress record. + ## Most likely the hostname above will be enough, but in the event more hosts are needed, this is an array + ## extraHosts: + ## - name: discourse.local + ## path: / + extraHosts: [] + ## @param ingress.extraTls The tls configuration for additional hostnames to be covered with this ingress record. + ## see: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + ## extraTls: + ## - hosts: + ## - discourse.local + ## secretName: discourse.local-tls + extraTls: [] + ## @param ingress.secrets If you're providing your own certificates, please use this to add the certificates as secrets + ## key and certificate should start with -----BEGIN CERTIFICATE----- or + ## -----BEGIN RSA PRIVATE KEY----- + ## + ## name should line up with a tlsSecret set further up + ## If you're using cert-manager, this is unneeded, as it will create the secret for you if it is not set + ## + ## It is also possible to create and manage the certificates outside of this helm chart + ## Please see README.md for more information + ## Example: + ## - name: discourse.local-tls + ## key: + ## certificate: + secrets: [] + +## @section Database parameters + +## PostgreSQL chart configuration +## https://github.com/bitnami/charts/blob/master/bitnami/postgresql/values.yaml +## +postgresql: + ## @param postgresql.enabled Deploy PostgreSQL container(s) + ## + enabled: true + ## @param postgresql.postgresqlUsername PostgreSQL user to create (used by Discourse). Has superuser privileges if username is `postgres`. + ## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run + ## + postgresqlUsername: bn_discourse + ## @param postgresql.postgresqlPassword PostgreSQL password + ## Defaults to a random 10-character alphanumeric string if not set + ## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run + ## + postgresqlPassword: "" + ## @param postgresql.postgresqlPostgresPassword PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`) + ## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) + ## + postgresqlPostgresPassword: 'bitnami' + ## @param postgresql.existingSecret Name of existing secret object + ## The secret should contain the following keys: + ## postgresql-postgres-password (for root user) + ## postgresql-password (for the unprivileged user) + ## + existingSecret: "" + ## @param postgresql.postgresqlDatabase Name of the database to create + ## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run + ## + postgresqlDatabase: bitnami_application + ## @param postgresql.persistence.enabled Enable database persistence using PVC + ## + persistence: + enabled: true +## External database configuration +## +externalDatabase: + ## @param externalDatabase.host Host of the external database + ## + host: "" + ## @param externalDatabase.port Database port number (when using an external db) + ## + port: 5432 + ## @param externalDatabase.user Non-root PostgreSQL username (when using an external db) + ## + user: bn_discourse + ## @param externalDatabase.password Password for the above username (when using an external db) + ## + password: "" + ## @param externalDatabase.create PostgreSQL create user/database + ## If true it will add POSTGRESQL_CLIENT_* env vars to the deployment which will create the PostgreSQL user & database using the provided admin credentials + ## + create: true + ## @param externalDatabase.postgresqlPostgresUser PostgreSQL admin user, used during the installation stage (when using an external db) + ## + postgresqlPostgresUser: "" + ## @param externalDatabase.postgresqlPostgresPassword PostgreSQL admin password used in the installation stage (when using an external db) + ## + postgresqlPostgresPassword: "" + ## @param externalDatabase.existingSecret Name of existing secret object + ## The secret should contain the following keys: + ## postgresql-postgres-password (for root user) + ## postgresql-password (for the unprivileged user) + ## + existingSecret: "" + ## @param externalDatabase.database Name of the existing database (when using an external db) + ## + database: bitnami_application + +## @section Redis™ parameters + +## Redis™ chart configuration +## https://github.com/bitnami/charts/blob/master/bitnami/redis/values.yaml +## +redis: + ## @param redis.enabled Whether to deploy a redis server to satisfy the applications requirements. To use an external redis instance set this to false and configure the externalRedis parameters + ## + enabled: true + ## Use password authentication + ## @param redis.auth.enabled Use password authentication + ## @param redis.auth.password Redis™ password (both master and replica) + ## @param redis.auth.existingSecret Name of an existing Kubernetes secret object containing the password + ## @param redis.auth.existingSecretPasswordKey Name of the key pointing to the password in your Kubernetes secret + ## + auth: + enabled: false + ## Defaults to a random 10-character alphanumeric string if not set and auth.enabled is true. + ## It should always be set using the password value or in the existingSecret to avoid issues + ## with Discourse. + ## The password value is ignored if existingSecret is set + password: "" + existingSecret: "" + existingSecretPasswordKey: 'redis-password' + ## @param redis.architecture Cluster settings + ## + architecture: standalone + ## Redis™ Master parameters + ## @param redis.master.persistence.enabled Enable database persistence using PVC + ## + master: + persistence: + enabled: true +## External Redis™ +## @param externalRedis.host Host of the external database +## @param externalRedis.port Database port number +## @param externalRedis.password Password for the external Redis. Ignored if existingSecret is set +## @param externalRedis.existingSecret Name of an existing Kubernetes secret object containing the password +## @param externalRedis.existingSecretPasswordKey Name of the key pointing to the password in your Kubernetes secret +## +externalRedis: + host: "" + port: 6379 + password: "" + existingSecret: "" + existingSecretPasswordKey: 'redis-password'