diff --git a/Chart.lock b/Chart.lock index 961e4fa..afc2440 100644 --- a/Chart.lock +++ b/Chart.lock @@ -8,5 +8,5 @@ dependencies: - name: redis repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami version: 16.13.2 -digest: sha256:17ea58a3264aa22faff18215c4269f47dabae956d0df273c684972f356416193 -generated: "2022-08-08T21:44:18.0195364+02:00" +digest: sha256:8be2c8069d65f295d0079bdda67c45691370f7bef73393c2e80eedbdd748b9af +generated: "2024-01-19T13:45:12.079125474+01:00" diff --git a/Chart.yaml b/Chart.yaml index 1ebc973..0809c9a 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -15,12 +15,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 4.0.0 +version: 4.1.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: v4.0.2 +appVersion: v4.2.5 dependencies: - name: elasticsearch diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 6331a26..2c50146 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -31,12 +31,22 @@ Create chart name and version as used by the chart label. {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} +{{/* +Labels added on every Mastodon resource +*/}} +{{- define "mastodon.globalLabels" -}} +{{- range $k, $v := .Values.mastodon.labels }} +{{ $k }}: {{ quote $v }} +{{- end -}} +{{- end }} + {{/* Common labels */}} {{- define "mastodon.labels" -}} helm.sh/chart: {{ include "mastodon.chart" . }} {{ include "mastodon.selectorLabels" . }} +{{ include "mastodon.globalLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -161,3 +171,16 @@ Find highest number of needed database connections to set DB_POOL variable {{- end }} {{- $poolSize | quote }} {{- end }} + +{{/* +Full hostname for a custom Elasticsearch cluster +*/}} +{{- define "mastodon.elasticsearch.fullHostname" -}} +{{- if not .Values.elasticsearch.enabled }} + {{- if .Values.elasticsearch.tls }} + {{- printf "https://%s" (tpl .Values.elasticsearch.hostname $) -}} + {{- else -}} + {{- printf "%s" (tpl .Values.elasticsearch.hostname $) -}} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/templates/_statsd.yaml b/templates/_statsd.yaml new file mode 100644 index 0000000..410e4f1 --- /dev/null +++ b/templates/_statsd.yaml @@ -0,0 +1,54 @@ +{{/* + The exporter container attached to every Mastodon pod +*/}} + +{{- define "mastodon.statsdExporterContainer" }} +{{- with .Values.mastodon.metrics.statsd }} +{{- if and .exporter.enabled (not .address) }} +- name: statsd-exporter + image: prom/statsd-exporter + args: + - "--statsd.mapping-config=/statsd-mappings/mastodon.yml" + resources: + requests: + cpu: "0.1" + memory: "180M" + limits: + cpu: "0.5" + memory: "250M" + ports: + - name: statsd + containerPort: {{ .exporter.port }} + volumeMounts: + - name: statsd-mappings + mountPath: /statsd-mappings +{{- end }} +{{- end }} +{{- end }} + +{{/* + The volume needed for the container above +*/}} +{{- define "mastodon.statsdExporterVolume" }} +{{- with .Values.mastodon.metrics.statsd }} +{{- if and .exporter.enabled (not .address) }} +- name: statsd-mappings + configMap: + name: {{ include "mastodon.fullname" $ }}-statsd-mappings + items: + - key: mastodon-statsd-mappings.yml + path: mastodon.yml +{{- end }} +{{- end }} +{{- end }} + +{{/* + Labels added to every statsd_exporter-enabled pod +*/}} +{{- define "mastodon.statsdExporterLabels" }} +{{- with .Values.mastodon.metrics.statsd }} +{{- if and .exporter.enabled (not .address) }} +mastodon/statsd-exporter: "true" +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/configmap-env.yaml b/templates/configmap-env.yaml index fbb8788..f2d989e 100644 --- a/templates/configmap-env.yaml +++ b/templates/configmap-env.yaml @@ -15,12 +15,36 @@ data: DB_NAME: {{ .Values.postgresql.auth.database }} DB_POOL: {{ include "mastodon.maxDbPool" . }} DB_USER: {{ .Values.postgresql.auth.username }} + {{- if .Values.postgresql.readReplica.hostname }} + REPLICA_DB_HOST: {{ .Values.postgresql.readReplica.hostname }} + {{- end }} + {{- if .Values.postgresql.readReplica.port }} + REPLICA_DB_PORT: {{ .Values.postgresql.readReplica.port }} + {{- end }} + {{- if .Values.postgresql.readReplica.auth.database }} + REPLICA_DB_NAME: {{ .Values.postgresql.readReplica.auth.database }} + {{- end }} + {{- if .Values.postgresql.readReplica.auth.username }} + REPLICA_DB_USER: {{ .Values.postgresql.readReplica.auth.username }} + {{- end }} + {{- if .Values.postgresql.readReplica.auth.password }} + REPLICA_DB_PASS: {{ .Values.postgresql.readReplica.auth.password }} + {{- end }} PREPARED_STATEMENTS: {{ .Values.mastodon.preparedStatements | quote }} DEFAULT_LOCALE: {{ .Values.mastodon.locale }} {{- if .Values.elasticsearch.enabled }} ES_ENABLED: "true" + ES_PRESET: {{ .Values.elasticsearch.preset | default "single_node_cluster" | quote }} ES_HOST: {{ template "mastodon.elasticsearch.fullname" . }}-master-hl ES_PORT: "9200" + {{- else if .Values.elasticsearch.hostname }} + ES_ENABLED: "true" + ES_PRESET: {{ .Values.elasticsearch.preset | default "single_node_cluster" | quote }} + ES_HOST: {{ include "mastodon.elasticsearch.fullHostname" .}} + ES_PORT: {{ .Values.elasticsearch.port | default "9200" | quote }} + {{- end }} + {{- with .Values.elasticsearch.user }} + ES_USER: {{ . }} {{- end }} LOCAL_DOMAIN: {{ .Values.mastodon.local_domain }} {{- with .Values.mastodon.web_domain }} @@ -325,6 +349,31 @@ data: LDAP_UID_CONVERSION_REPLACE: {{ . }} {{- end }} {{- end }} - {{- with .Values.mastodon.metrics.statsd.address }} - STATSD_ADDR: {{ . }} + {{- if .Values.mastodon.metrics.statsd.address }} + STATSD_ADDR: {{ .Values.mastodon.metrics.statsd.address }} + {{- else if .Values.mastodon.metrics.statsd.exporter.enabled }} + STATSD_ADDR: localhost:9125 + {{- end }} + {{- range $k, $v := .Values.mastodon.extraEnvVars }} + {{ $k }}: {{ quote $v }} + {{- end }} + + {{- if .Values.mastodon.deepl.enabled }} + DEEPL_PLAN: {{ .Values.mastodon.deepl.plan }} + {{- end }} + + {{- if .Values.mastodon.hcaptcha.enabled }} + HCAPTCHA_SITE_KEY: {{ .Values.mastodon.hcaptcha.siteId }} + {{- end }} + + {{- if .Values.mastodon.cacheBuster.enabled }} + CACHE_BUSTER_ENABLED: "true" + {{- if .Values.mastodon.cacheBuster.httpMethod }} + CACHE_BUSTER_HTTP_METHOD: {{ .Values.mastodon.cacheBuster.httpMethod }} + {{- end }} + {{- if .Values.mastodon.cacheBuster.authHeader }} + CACHE_BUSTER_SECRET_HEADER: {{ .Values.mastodon.cacheBuster.authHeader }} + {{- end }} + {{- else }} + CACHE_BUSTER_ENABLED: "false" {{- end }} diff --git a/templates/cronjob-media-remove.yaml b/templates/cronjob-media-remove.yaml index d70afeb..33229a8 100644 --- a/templates/cronjob-media-remove.yaml +++ b/templates/cronjob-media-remove.yaml @@ -65,6 +65,13 @@ spec: secretKeyRef: name: {{ template "mastodon.redis.secretName" . }} key: redis-password + {{- if and .Values.elasticsearch.existingSecret (or .Values.elasticsearch.enabled .Values.elasticsearch.hostname) }} + - name: "ES_PASS" + valueFrom: + secretKeyRef: + name: {{ .Values.elasticsearch.existingSecret }} + key: password + {{- end }} - name: "PORT" value: {{ .Values.mastodon.web.port | quote }} {{- if (and .Values.mastodon.s3.enabled .Values.mastodon.s3.existingSecret) }} diff --git a/templates/deployment-sidekiq.yaml b/templates/deployment-sidekiq.yaml index 8b1a014..cb98dc2 100644 --- a/templates/deployment-sidekiq.yaml +++ b/templates/deployment-sidekiq.yaml @@ -22,6 +22,7 @@ spec: type: Recreate {{- end }} replicas: {{ .replicas }} + revisionHistoryLimit: 2 selector: matchLabels: {{- include "mastodon.selectorLabels" $context | nindent 6 }} @@ -35,9 +36,11 @@ spec: {{- end }} # roll the pods to pick up any db migrations or other changes {{- include "mastodon.rollingPodAnnotations" $context | nindent 8 }} - checksum/config-secrets: {{ include ( print $.Template.BasePath "/secret-smtp.yaml" ) $context | sha256sum | quote }} + checksum/config-secrets-smtp: {{ include ( print $.Template.BasePath "/secret-smtp.yaml" ) $context | sha256sum | quote }} labels: + {{- include "mastodon.globalLabels" $context | nindent 8 }} {{- include "mastodon.selectorLabels" $context | nindent 8 }} + {{- include "mastodon.statsdExporterLabels" $context | nindent 8 }} app.kubernetes.io/component: sidekiq-{{ .name }} app.kubernetes.io/part-of: rails spec: @@ -54,8 +57,12 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} - {{- if (not $context.Values.mastodon.s3.enabled) }} + {{- with (default (default $context.Values.topologySpreadConstraints $context.Values.mastodon.sidekiq.topologySpreadConstraints) .topologySpreadConstraints) }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} volumes: + {{- if (not $context.Values.mastodon.s3.enabled) }} - name: assets persistentVolumeClaim: claimName: {{ template "mastodon.fullname" $context }}-assets @@ -63,11 +70,20 @@ spec: persistentVolumeClaim: claimName: {{ template "mastodon.fullname" $context }}-system {{- end }} + {{- include "mastodon.statsdExporterVolume" $ | indent 8 }} + {{- if dig "customDatabaseConfigYml" "configMapRef" "name" false . }} + - name: config-database-yml + configMap: + name: {{ .customDatabaseConfigYml.configMapRef.name }} + {{- end }} + {{- with $context.Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} containers: - name: {{ $context.Chart.Name }} securityContext: {{- toYaml $context.Values.mastodon.sidekiq.securityContext | nindent 12 }} - image: "{{ $context.Values.image.repository }}:{{ $context.Values.image.tag | default $context.Chart.AppVersion }}" + image: "{{ coalesce (dig "image" "repository" false .) $context.Values.image.repository }}:{{ coalesce (dig "image" "tag" false .) $context.Values.image.tag $context.Chart.AppVersion }}" imagePullPolicy: {{ $context.Values.image.pullPolicy }} command: - bundle @@ -94,11 +110,25 @@ spec: secretKeyRef: name: {{ template "mastodon.postgresql.secretName" $context }} key: password + {{- if $context.Values.postgresql.readReplica.auth.existingSecret }} + - name: "REPLICA_DB_PASS" + valueFrom: + secretKeyRef: + name: {{ $context.Values.postgresql.readReplica.auth.existingSecret }} + key: password + {{- end }} - name: "REDIS_PASSWORD" valueFrom: secretKeyRef: name: {{ template "mastodon.redis.secretName" $context }} key: redis-password + {{- if and $context.Values.elasticsearch.existingSecret (or $context.Values.elasticsearch.enabled $context.Values.elasticsearch.hostname) }} + - name: "ES_PASS" + valueFrom: + secretKeyRef: + name: {{ $context.Values.elasticsearch.existingSecret }} + key: password + {{- end }} - name: "SMTP_LOGIN" valueFrom: secretKeyRef: @@ -122,15 +152,38 @@ spec: name: {{ $context.Values.mastodon.s3.existingSecret }} key: AWS_ACCESS_KEY_ID {{- end }} - {{- if (not $context.Values.mastodon.s3.enabled) }} + {{- if and $context.Values.mastodon.deepl.enabled }} + - name: "DEEPL_API_KEY" + valueFrom: + secretKeyRef: + name: {{ $context.Values.mastodon.deepl.apiKeySecretRef.name }} + key: {{ $context.Values.mastodon.deepl.apiKeySecretRef.key }} + {{- end }} + {{- if and $context.Values.mastodon.cacheBuster.enabled $context.Values.mastodon.cacheBuster.authToken.existingSecret }} + - name: CACHE_BUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ $context.Values.mastodon.cacheBuster.authToken.existingSecret }} + key: password + {{- end }} volumeMounts: + {{- if (not $context.Values.mastodon.s3.enabled) }} - name: assets mountPath: /opt/mastodon/public/assets - name: system mountPath: /opt/mastodon/public/system {{- end }} + {{- if dig "customDatabaseConfigYml" "configMapRef" "name" false . }} + - name: config-database-yml + mountPath: /opt/mastodon/config/database.yml + subPath: {{ .customDatabaseConfigYml.configMapRef.key }} + {{- end }} + {{- with $context.Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} resources: {{- toYaml (default (default $context.Values.resources $context.Values.mastodon.sidekiq.resources) .resources) | nindent 12 }} + {{- include "mastodon.statsdExporterContainer" $ | indent 8 }} {{- with $context.Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/templates/deployment-streaming.yaml b/templates/deployment-streaming.yaml index 704ebe1..b3c26bd 100644 --- a/templates/deployment-streaming.yaml +++ b/templates/deployment-streaming.yaml @@ -10,6 +10,7 @@ metadata: {{- end }} spec: replicas: {{ .Values.mastodon.streaming.replicas }} + revisionHistoryLimit: 2 selector: matchLabels: {{- include "mastodon.selectorLabels" . | nindent 6 }} @@ -23,6 +24,7 @@ spec: # roll the pods to pick up any db migrations or other changes {{- include "mastodon.rollingPodAnnotations" . | nindent 8 }} labels: + {{- include "mastodon.globalLabels" . | nindent 8 }} {{- include "mastodon.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: streaming spec: @@ -41,7 +43,7 @@ spec: securityContext: {{- toYaml . | nindent 12 }} {{- end }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: "{{ coalesce .Values.mastodon.streaming.image.repository .Values.image.repository }}:{{ coalesce .Values.mastodon.streaming.image.tag .Values.image.tag .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: - node @@ -59,6 +61,13 @@ spec: secretKeyRef: name: {{ template "mastodon.postgresql.secretName" . }} key: password + {{- if .Values.postgresql.readReplica.auth.existingSecret }} + - name: "REPLICA_DB_PASS" + valueFrom: + secretKeyRef: + name: {{ .Values.postgresql.readReplica.auth.existingSecret }} + key: password + {{- end }} - name: "REDIS_PASSWORD" valueFrom: secretKeyRef: @@ -90,6 +99,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with (default .Values.topologySpreadConstraints .Values.mastodon.streaming.topologySpreadConstraints) }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/templates/deployment-web.yaml b/templates/deployment-web.yaml index 5e4dcfe..28490a7 100644 --- a/templates/deployment-web.yaml +++ b/templates/deployment-web.yaml @@ -10,6 +10,7 @@ metadata: {{- end }} spec: replicas: {{ .Values.mastodon.web.replicas }} + revisionHistoryLimit: 2 selector: matchLabels: {{- include "mastodon.selectorLabels" . | nindent 6 }} @@ -24,7 +25,9 @@ spec: # roll the pods to pick up any db migrations or other changes {{- include "mastodon.rollingPodAnnotations" . | nindent 8 }} labels: + {{- include "mastodon.globalLabels" . | nindent 8 }} {{- include "mastodon.selectorLabels" . | nindent 8 }} + {{- include "mastodon.statsdExporterLabels" . | nindent 8 }} app.kubernetes.io/component: web app.kubernetes.io/part-of: rails spec: @@ -37,8 +40,8 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} - {{- if (not .Values.mastodon.s3.enabled) }} volumes: + {{- if (not .Values.mastodon.s3.enabled) }} - name: assets persistentVolumeClaim: claimName: {{ template "mastodon.fullname" . }}-assets @@ -46,13 +49,22 @@ spec: persistentVolumeClaim: claimName: {{ template "mastodon.fullname" . }}-system {{- end }} + {{- include "mastodon.statsdExporterVolume" $ | indent 8 }} + {{- if .Values.mastodon.web.customDatabaseConfigYml.configMapRef.name }} + - name: config-database-yml + configMap: + name: {{ .Values.mastodon.web.customDatabaseConfigYml.configMapRef.name }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} containers: - name: {{ .Chart.Name }}-web {{- with (default .Values.securityContext .Values.mastodon.web.securityContext) }} securityContext: {{- toYaml . | nindent 12 }} {{- end }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: "{{ coalesce .Values.mastodon.web.image.repository .Values.image.repository }}:{{ coalesce .Values.mastodon.web.image.tag .Values.image.tag .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: - bundle @@ -75,11 +87,25 @@ spec: secretKeyRef: name: {{ template "mastodon.postgresql.secretName" . }} key: password + {{- if .Values.postgresql.readReplica.auth.existingSecret }} + - name: "REPLICA_DB_PASS" + valueFrom: + secretKeyRef: + name: {{ .Values.postgresql.readReplica.auth.existingSecret}} + key: password + {{- end }} - name: "REDIS_PASSWORD" valueFrom: secretKeyRef: name: {{ template "mastodon.redis.secretName" . }} key: redis-password + {{- if and .Values.elasticsearch.existingSecret (or .Values.elasticsearch.enabled .Values.elasticsearch.hostname) }} + - name: "ES_PASS" + valueFrom: + secretKeyRef: + name: {{ .Values.elasticsearch.existingSecret }} + key: password + {{- end }} - name: "PORT" value: {{ .Values.mastodon.web.port | quote }} {{- if .Values.mastodon.web.minThreads }} @@ -110,13 +136,42 @@ spec: name: {{ .Values.mastodon.s3.existingSecret }} key: AWS_ACCESS_KEY_ID {{- end }} - {{- if (not .Values.mastodon.s3.enabled) }} + {{- if .Values.mastodon.deepl.enabled }} + - name: "DEEPL_API_KEY" + valueFrom: + secretKeyRef: + name: {{ .Values.mastodon.deepl.apiKeySecretRef.name }} + key: {{ .Values.mastodon.deepl.apiKeySecretRef.key }} + {{- end }} + {{- if .Values.mastodon.hcaptcha.enabled }} + - name: "HCAPTCHA_SECRET_KEY" + valueFrom: + secretKeyRef: + name: {{ .Values.mastodon.hcaptcha.secretKeySecretRef.name }} + key: {{ .Values.mastodon.hcaptcha.secretKeySecretRef.key }} + {{- end }} + {{- if and .Values.mastodon.cacheBuster.enabled .Values.mastodon.cacheBuster.authToken.existingSecret }} + - name: CACHE_BUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.mastodon.cacheBuster.authToken.existingSecret }} + key: password + {{- end }} volumeMounts: + {{- if (not .Values.mastodon.s3.enabled) }} - name: assets mountPath: /opt/mastodon/public/assets - name: system mountPath: /opt/mastodon/public/system {{- end }} + {{- if .Values.mastodon.web.customDatabaseConfigYml.configMapRef.name }} + - name: config-database-yml + mountPath: /opt/mastodon/config/database.yml + subPath: {{ .Values.mastodon.web.customDatabaseConfigYml.configMapRef.key }} + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} ports: - name: http containerPort: {{ .Values.mastodon.web.port }} @@ -138,6 +193,7 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- include "mastodon.statsdExporterContainer" $ | indent 8 }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -146,7 +202,11 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.tolerations }} + {{- with (default .Values.topologySpreadConstraints .Values.mastodon.web.topologySpreadConstraints) }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with (default .Values.tolerations .Values.mastodon.web.tolerations) }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} diff --git a/templates/ingress-streaming.yml b/templates/ingress-streaming.yml new file mode 100644 index 0000000..4e3ad72 --- /dev/null +++ b/templates/ingress-streaming.yml @@ -0,0 +1,57 @@ +{{- if .Values.ingress.streaming.enabled -}} +{{- $fullName := include "mastodon.fullname" . -}} +{{- $webPort := .Values.mastodon.web.port -}} +{{- $streamingPort := .Values.mastodon.streaming.port -}} +{{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }}-streaming + labels: + {{- include "mastodon.labels" . | nindent 4 }} + {{- with .Values.ingress.streaming.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.streaming.ingressClassName }} + ingressClassName: {{ .Values.ingress.streaming.ingressClassName }} + {{- end }} + {{- if .Values.ingress.streaming.tls }} + tls: + {{- range .Values.ingress.streaming.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.streaming.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }}api/v1/streaming + backend: + {{- if or ($.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not ($.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + service: + name: {{ $fullName }}-streaming + port: + number: {{ $streamingPort }} + {{- else }} + serviceName: {{ $fullName }}-streaming + servicePort: {{ $streamingPort }} + {{- end }} + {{- if or ($.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not ($.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + pathType: Prefix + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/templates/ingress.yaml b/templates/ingress.yaml index 5a3409a..3da46ab 100644 --- a/templates/ingress.yaml +++ b/templates/ingress.yaml @@ -52,6 +52,7 @@ spec: {{- if or ($.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not ($.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} pathType: Prefix {{- end }} + {{- if not $.Values.ingress.streaming.enabled }} - path: {{ .path }}api/v1/streaming backend: {{- if or ($.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not ($.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} @@ -67,5 +68,6 @@ spec: pathType: Prefix {{- end }} {{- end }} + {{- end }} {{- end }} {{- end }} diff --git a/templates/job-assets-precompile.yaml b/templates/job-assets-precompile.yaml index bc5ff7b..3458fea 100644 --- a/templates/job-assets-precompile.yaml +++ b/templates/job-assets-precompile.yaml @@ -1,3 +1,4 @@ +{{- if .Values.mastodon.hooks.assetsPrecompile.enabled -}} apiVersion: batch/v1 kind: Job metadata: @@ -75,3 +76,4 @@ spec: - name: system mountPath: /opt/mastodon/public/system {{- end }} +{{- end -}} diff --git a/templates/job-chewy-upgrade.yaml b/templates/job-chewy-upgrade.yaml index f86a4e3..33e9bf9 100644 --- a/templates/job-chewy-upgrade.yaml +++ b/templates/job-chewy-upgrade.yaml @@ -67,6 +67,13 @@ spec: secretKeyRef: name: {{ template "mastodon.redis.secretName" . }} key: redis-password + {{- if and .Values.elasticsearch.existingSecret (or .Values.elasticsearch.enabled .Values.elasticsearch.hostname) }} + - name: "ES_PASS" + valueFrom: + secretKeyRef: + name: {{ .Values.elasticsearch.existingSecret }} + key: password + {{- end }} - name: "PORT" value: {{ .Values.mastodon.web.port | quote }} {{- if (not .Values.mastodon.s3.enabled) }} diff --git a/templates/job-db-migrate.yaml b/templates/job-db-migrate.yaml index 41324fb..e9a40a7 100644 --- a/templates/job-db-migrate.yaml +++ b/templates/job-db-migrate.yaml @@ -1,3 +1,4 @@ +{{- if .Values.mastodon.hooks.dbMigrate.enabled -}} apiVersion: batch/v1 kind: Job metadata: @@ -75,3 +76,4 @@ spec: - name: system mountPath: /opt/mastodon/public/system {{- end }} +{{- end -}} diff --git a/templates/pvc-assets.yaml b/templates/pvc-assets.yaml index 36d5558..46c90ca 100644 --- a/templates/pvc-assets.yaml +++ b/templates/pvc-assets.yaml @@ -7,7 +7,7 @@ metadata: {{- include "mastodon.labels" . | nindent 4 }} spec: accessModes: - - {{ .Values.mastodon.persistence.system.accessMode }} + - {{ .Values.mastodon.persistence.assets.accessMode }} {{- with .Values.mastodon.persistence.assets.resources }} resources: {{- toYaml . | nindent 4 }} diff --git a/templates/statsd-exporter-mappings.yaml b/templates/statsd-exporter-mappings.yaml new file mode 100644 index 0000000..813af1d --- /dev/null +++ b/templates/statsd-exporter-mappings.yaml @@ -0,0 +1,107 @@ +{{- if and .Values.mastodon.metrics.statsd.exporter.enabled (not .Values.mastodon.metrics.statsd.address) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mastodon.fullname" . }}-statsd-mappings + labels: + {{- include "mastodon.labels" . | nindent 4 }} +data: + mastodon-statsd-mappings.yml: |- + ## From https://ipng.ch/assets/mastodon/statsd-mapping.yaml + ## Prometheus Statsd Exporter mapping for Mastodon 4.0+ + ## + ## Version 1.0, November 2022 + ## + ## Documentation: https://ipng.ch/s/articles/2022/11/27/mastodon-3.html + + mappings: + ## Web collector + - match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.status\.(.+) + match_type: regex + name: "mastodon_controller_status" + labels: + controller: $1 + action: $2 + format: $3 + status: $4 + mastodon: "web" + - match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.db_time + match_type: regex + name: "mastodon_controller_db_time" + labels: + controller: $1 + action: $2 + format: $3 + mastodon: "web" + - match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.view_time + match_type: regex + name: "mastodon_controller_view_time" + labels: + controller: $1 + action: $2 + format: $3 + mastodon: "web" + - match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.total_duration + match_type: regex + name: "mastodon_controller_duration" + labels: + controller: $1 + action: $2 + format: $3 + mastodon: "web" + + ## Database collector + - match: Mastodon\.production\.db\.tables\.(.+)\.queries\.(.+)\.duration + match_type: regex + name: "mastodon_db_operation" + labels: + table: "$1" + operation: "$2" + mastodon: "db" + + ## Cache collector + - match: Mastodon\.production\.cache\.(.+)\.duration + match_type: regex + name: "mastodon_cache_duration" + labels: + operation: "$1" + mastodon: "cache" + + ## Sidekiq collector + - match: Mastodon\.production\.sidekiq\.(.+)\.processing_time + match_type: regex + name: "mastodon_sidekiq_worker_processing_time" + labels: + worker: "$1" + mastodon: "sidekiq" + - match: Mastodon\.production\.sidekiq\.(.+)\.success + match_type: regex + name: "mastodon_sidekiq_worker_success_total" + labels: + worker: "$1" + mastodon: "sidekiq" + - match: Mastodon\.production\.sidekiq\.(.+)\.failure + match_type: regex + name: "mastodon_sidekiq_worker_failure_total" + labels: + worker: "$1" + mastodon: "sidekiq" + - match: Mastodon\.production\.sidekiq\.queues\.(.+)\.enqueued + match_type: regex + name: "mastodon_sidekiq_queue_enqueued" + labels: + queue: "$1" + mastodon: "sidekiq" + - match: Mastodon\.production\.sidekiq\.queues\.(.+)\.latency + match_type: regex + name: "mastodon_sidekiq_queue_latency" + labels: + queue: "$1" + mastodon: "sidekiq" + - match: Mastodon\.production\.sidekiq\.(.+) + match_type: regex + name: "mastodon_sidekiq_$1" + labels: + mastodon: "sidekiq" + +{{- end }} diff --git a/values.yaml b/values.yaml index fa53bab..8378928 100644 --- a/values.yaml +++ b/values.yaml @@ -6,11 +6,14 @@ image: # built from the most recent commit # # tag: latest - tag: "" + tag: "v4.2.5" # use `Always` when using `latest` tag pullPolicy: IfNotPresent mastodon: + # Labels added to every Mastodon-related object + labels: {} + # -- create an initial administrator user; the password is autogenerated and will # have to be reset createAdmin: @@ -20,6 +23,13 @@ mastodon: username: not_gargron # @ignored email: not@example.com + hooks: + dbMigrate: + enabled: true + assetsPrecompile: + enabled: true + # Custom labels to add to kubernetes resources + #labels: cron: # -- run `tootctl media remove` every week removeMedia: @@ -38,7 +48,7 @@ mastodon: singleUserMode: false # -- Enables "Secure Mode" for more details see: https://docs.joinmastodon.org/admin/config/#authorized_fetch authorizedFetch: false - # -- Enables "Limited Federation Mode" for more detauls see: https://docs.joinmastodon.org/admin/config/#limited_federation_mode + # -- Enables "Limited Federation Mode" for more details see: https://docs.joinmastodon.org/admin/config/#limited_federation_mode limitedFederationMode: false persistence: assets: @@ -68,6 +78,18 @@ mastodon: permission: "" # -- If you have a caching proxy, enter its base URL here. alias_host: "" + deepl: + enabled: false + plan: + apiKeySecretRef: + name: + key: + hcaptcha: + enabled: false + siteId: + secretKeySecretRef: + name: + key: # these must be set manually; autogenerated keys are rotated on each upgrade secrets: secret_key_base: "" @@ -88,6 +110,8 @@ mastodon: resources: {} # -- Affinity for all Sidekiq Deployments unless overwritten, overwrites .Values.affinity affinity: {} + # -- Topology spread constraints for Sidekiq Pods, overwrites .Values.topologySpreadConstraints + topologySpreadConstraints: {} # limits: # cpu: "1" # memory: 768Mi @@ -95,24 +119,35 @@ mastodon: # cpu: 250m # memory: 512Mi workers: - - name: all-queues - # -- Number of threads / parallel sidekiq jobs that are executed per Pod - concurrency: 25 - # -- Number of Pod replicas deployed by the Deployment - replicas: 1 - # -- Resources for this specific deployment to allow optimised scaling, overwrites .Values.mastodon.sidekiq.resources - resources: {} - # -- Affinity for this specific deployment, overwrites .Values.affinity and .Values.mastodon.sidekiq.affinity - affinity: {} - # -- Sidekiq queues for Mastodon that are handled by this worker. See https://docs.joinmastodon.org/admin/scaling/#concurrency - # See https://github.com/mperham/sidekiq/wiki/Advanced-Options#queues for how to weight queues as argument - queues: - - default,8 - - push,6 - - ingress,4 - - mailers,2 - - pull - - scheduler # Make sure the scheduler queue only exists once and with a worker that has 1 replica. + - name: all-queues + # -- Number of threads / parallel sidekiq jobs that are executed per Pod + concurrency: 25 + # -- Number of Pod replicas deployed by the Deployment + replicas: 1 + # -- Resources for this specific deployment to allow optimised scaling, overwrites .Values.mastodon.sidekiq.resources + resources: {} + # -- Affinity for this specific deployment, overwrites .Values.affinity and .Values.mastodon.sidekiq.affinity + affinity: {} + # -- Topology spread constraints for this specific deployment, overwrites .Values.topologySpreadConstraints and .Values.mastodon.sidekiq.topologySpreadConstraints + topologySpreadConstraints: {} + # -- Sidekiq queues for Mastodon that are handled by this worker. See https://docs.joinmastodon.org/admin/scaling/#concurrency + # See https://github.com/mperham/sidekiq/wiki/Advanced-Options#queues for how to weight queues as argument + queues: + - default,8 + - push,6 + - ingress,4 + - mailers,2 + - pull + - scheduler # Make sure the scheduler queue only exists once and with a worker that has 1 replica. + image: + repository: + tag: + # allows you to mount a custom database.yml from a configmap + # please note that we do not advise using a read-only replica for sidekiq workers + customDatabaseConfigYml: + configMapRef: + name: + key: #- name: push-pull # concurrency: 50 # resources: {} @@ -135,7 +170,7 @@ mastodon: ca_file: /etc/ssl/certs/ca-certificates.crt delivery_method: smtp domain: - enable_starttls: 'auto' + enable_starttls: "auto" from_address: notifications@example.com return_path: openssl_verify_mode: peer @@ -149,6 +184,9 @@ mastodon: # password must be located in keys named `login` and `password` respectively. existingSecret: streaming: + image: + repository: + tag: port: 4000 # -- this should be set manually since os.cpus() returns the number of CPUs on # the node running the pod, which is unrelated to the resources allocated to @@ -161,6 +199,8 @@ mastodon: replicas: 1 # -- Affinity for Streaming Pods, overwrites .Values.affinity affinity: {} + # -- Topology spread constraints for Streaming Pods, overwrites .Values.topologySpreadConstraints + topologySpreadConstraints: {} # -- Pod Security Context for Streaming Pods, overwrites .Values.podSecurityContext podSecurityContext: {} # -- (Streaming Container) Security Context for Streaming Pods, overwrites .Values.securityContext @@ -179,6 +219,8 @@ mastodon: replicas: 1 # -- Affinity for Web Pods, overwrites .Values.affinity affinity: {} + # -- Topology spread constraints for Web Pods, overwrites .Values.topologySpreadConstraints + topologySpreadConstraints: {} # -- Pod Security Context for Web Pods, overwrites .Values.podSecurityContext podSecurityContext: {} # -- (Web Container) Security Context for Web Pods, overwrites .Values.securityContext @@ -197,20 +239,51 @@ mastodon: maxThreads: "5" workers: "2" persistentTimeout: "20" + image: + repository: + tag: + # allows you to mount a custom database.yml from a configmap + # for example if you want to use a read-only replica + customDatabaseConfigYml: + configMapRef: + name: + key: + + # HTTP cache buster configuration. + # See the documentation for more information about this feature: + # https://docs.joinmastodon.org/admin/config/#http-cache-buster + cacheBuster: + enabled: false + httpMethod: "GET" + # If the cache service requires authentication, specify the header name and + # secret/token here. + authHeader: + authToken: + existingSecret: metrics: statsd: # -- Enable statsd publishing via STATSD_ADDR environment variable address: "" + # -- Alternatively, you can use this to have a statsd_exporter sidecar container running along all Mastodon containers and exposing metrics in OpenMetric/Prometheus format on each pod + # Please note the exporter will not be enabled if metrics.statsd.address is not empty + exporter: + enabled: false + port: 9102 # Sets the PREPARED_STATEMENTS environment variable: https://docs.joinmastodon.org/admin/config/#prepared_statements preparedStatements: true + # Specify extra environment variables to be added to all Mastodon pods. # These can be used for configuration not included in this chart (including configuration for Mastodon varietals.) + extraEnvVars: {} + + # Alternatively specify extra environment variables stored in a ConfigMap. # The specified ConfigMap should contain the additional environment variables in key-value format. # extraEnvFrom: + ingress: enabled: true annotations: @@ -231,25 +304,54 @@ ingress: hosts: - host: mastodon.local paths: - - path: '/' + - path: "/" tls: - secretName: mastodon-tls hosts: - mastodon.local + # This allows you to have a separate ingress for streaming + # When enabled, the main ingress will no longer handle streaming requests. + # You will also need to configure mastodon.streaming.base_url accordingly + streaming: + enabled: false + annotations: + ingressClassName: + hosts: + - host: streaming.mastodon.local + paths: + - path: "/" + tls: + - secretName: mastodon-tls + hosts: + - streaming.mastodon.local + # -- https://github.com/bitnami/charts/tree/master/bitnami/elasticsearch#parameters elasticsearch: - # `false` will disable full-text search + # Elasticsearch is powering full-text search. It is optional. + + # `false` will not install Elasticsearch as part of this chart # # if you enable ES after the initial install, you will need to manually run # RAILS_ENV=production bundle exec rake chewy:sync # (https://docs.joinmastodon.org/admin/optional/elasticsearch/) - # @ignored enabled: true # @ignored image: tag: 7 + # If you are using an external ES cluster, use `enabled: false` and set the hostname, port, + # and whether the cluster uses TLS. + # hostname: + # port: 9200 + # tls: true + # preset: single_node_cluster + + # This is optional, use it if you ES cluster requires authentication + # user: + # Name of an existing secret with a password key + # existingSecret: + # https://github.com/bitnami/charts/tree/master/bitnami/postgresql#parameters postgresql: # -- disable if you want to use an existing db; in which case the values below @@ -272,6 +374,20 @@ postgresql: # with a key of password set to the password you want existingSecret: "" + # Options for a read-only replica. + # If enabled, mastodon uses existing defaults for postgres for these values as well. + # NOTE: This feature is only available on Mastodon v4.2+ + # Documentation for more information on this feature: + # https://docs.joinmastodon.org/admin/scaling/#read-replicas + readReplica: + hostname: + port: + auth: + database: + username: + password: + existingSecret: + # https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters redis: # disable if you want to use an existing redis instance; in which case the @@ -286,6 +402,8 @@ redis: # you can also specify the name of an existing Secret # with a key of redis-password set to the password you want # existingSecret: "" + replica: + replicaCount: 0 # @ignored service: @@ -450,3 +568,15 @@ tolerations: [] # -- Affinity for all pods unless overwritten affinity: {} + +# -- Topology Spread Constraints for all pods unless overwritten +# Please note that you need to use `matchLabelKeys` (Kubernetes 1.25+) if you +# want to spread each deployment independently, or override topologySpreadConstraints +# for each deployment +topologySpreadConstraints: {} + +# Default volume mounts for all pods +volumeMounts: [] + +# Default volumes for all pods +volumes: []