diff --git a/.github/workflows/test-chart.yml b/.github/workflows/test-chart.yml index a4482b6..3e02fc6 100644 --- a/.github/workflows/test-chart.yml +++ b/.github/workflows/test-chart.yml @@ -76,7 +76,10 @@ jobs: # higher. # - k3s-channel: v1.21 - helm-version: v3.6.0 + helm-version: v3.8.0 + + env: + HELM_EXPERIMENTAL_OCI: "1" steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2b6c100 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,108 @@ +# 5.1.0 + +- Added values for Active Record Encryption in Redis: + ```yaml + mastodon: + secrets: + activeRecordEncryption: + primaryKey: + deterministicKey: + keyDerivationSalt: + ``` + +- Small bugfix related to automatic secret generation + +# [5.0.0](https://github.com/mastodon/chart/commit/63a052b6a5c19dabd172c15c1fd74298dcc544b2) + +- Updated major versions of chart dependencies (postgres, redis, elasticsearch) + +# [4.0.0](https://github.com/mastodon/chart/compare/920cf37..ae892d5) + +- adds support for multiple Sidekiq deployments to be configured to manage + different sets of queues. + +- smtp: replaces `enable_starttls_auto` boolean with `enable_starttls` setting + that defaults to `auto`. + +- adds support for statsd publishing: + ``` + mastodon: + metrics: + statsd: + address: + ``` + +- allows disabling the included redis deployment in order to use an existing external redis server: + ``` + redis: + enabled: false + ``` + +- adds support for [authorized + fetch](https://docs.joinmastodon.org/admin/config/#authorized_fetch): + ``` + mastodon: + authorizedFetch: true + ``` + +- removed the `HorizontalPodAutoscaler` and the global autoscaling configuration. + +A number of other configuration options have been added, see [values.yaml](./values.yaml). + +# 3.0.0 + +skipped + +# 2.1.0 + +## ingressClassName and tls-acme changes +The annotations previously defaulting to nginx have been removed and support + for ingressClassName has been added. +```yaml +ingress: + annotations: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" +``` + +To restore the old functionality simply add the above snippet to your `values.yaml`, +but the recommendation is to replace these with `ingress.ingressClassName` and use +cert-manager's issuer/cluster-issuer instead of tls-acme. +If you're uncertain about your current setup leave `ingressClassName` empty and add +`kubernetes.io/tls-acme` to `ingress.annotations` in your `values.yaml`. + +# 2.0.0 + +## Fixed labels +Because of the changes in [#19706](https://github.com/mastodon/mastodon/pull/19706) the upgrade may fail with the following error: +```Error: UPGRADE FAILED: cannot patch "mastodon-sidekiq"``` + +If you want an easy upgrade and you're comfortable with some downtime then +simply delete the -sidekiq, -web, and -streaming Deployments manually. + +If you require a no-downtime upgrade then: +1. run `helm template` instead of `helm upgrade` +2. Copy the new -web and -streaming services into `services.yml` +3. Copy the new -web and -streaming deployments into `deployments.yml` +4. Append -temp to the name of each deployment in `deployments.yml` +5. `kubectl apply -f deployments.yml` then wait until all pods are ready +6. `kubectl apply -f services.yml` +7. Delete the old -sidekiq, -web, and -streaming deployments manually +8. `helm upgrade` like normal +9. `kubectl delete -f deployments.yml` to clear out the temporary deployments + +## PostgreSQL passwords +If you've previously installed the chart and you're having problems with +postgres not accepting your password then make sure to set `username` to +`postgres` and `password` and `postgresPassword` to the same passwords. +```yaml +postgresql: + auth: + username: postgres + password: + postgresPassword: +``` + +And make sure to set `password` to the same value as `postgres-password` +in your `mastodon-postgresql` secret: +```kubectl edit secret mastodon-postgresql``` diff --git a/Chart.lock b/Chart.lock index afc2440..e985f1a 100644 --- a/Chart.lock +++ b/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: elasticsearch - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami - version: 19.0.1 + repository: oci://registry-1.docker.io/bitnamicharts + version: 19.19.2 - name: postgresql - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami - version: 11.1.3 + repository: oci://registry-1.docker.io/bitnamicharts + version: 14.2.3 - name: redis - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami - version: 16.13.2 -digest: sha256:8be2c8069d65f295d0079bdda67c45691370f7bef73393c2e80eedbdd748b9af -generated: "2024-01-19T13:45:12.079125474+01:00" + repository: oci://registry-1.docker.io/bitnamicharts + version: 18.16.1 +digest: sha256:684daaf2067d96e2aa6d93e9d29b7b13fc586f6ae929342e5e9c7c169b1c0748 +generated: "2024-02-23T15:14:47.536480528-08:00" diff --git a/Chart.yaml b/Chart.yaml index 0809c9a..2ee7189 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -12,26 +12,26 @@ description: Mastodon is a free, open-source social network server based on Acti # pipeline. Library charts do not define any templates and therefore cannot be deployed. 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. +# 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.1.1 +version: 5.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.2.5 +appVersion: v4.2.8 dependencies: - name: elasticsearch - version: 19.0.1 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + version: 19.19.2 + repository: oci://registry-1.docker.io/bitnamicharts condition: elasticsearch.enabled - name: postgresql - version: 11.1.3 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + version: 14.2.3 + repository: oci://registry-1.docker.io/bitnamicharts condition: postgresql.enabled - name: redis - version: 16.13.2 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami + version: 18.16.1 + repository: oci://registry-1.docker.io/bitnamicharts condition: redis.enabled diff --git a/README.md b/README.md index 53f9599..35303c0 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,18 @@ This is a [Helm](https://helm.sh/) chart for installing Mastodon into a Kubernetes cluster. The basic usage is: 1. edit `values.yaml` or create a separate yaml file for custom values -1. `helm dep update` +1. `helm dep install` 1. `helm install --namespace mastodon --create-namespace my-mastodon ./ -f path/to/additional/values.yaml` -This chart is tested with k8s 1.21+ and helm 3.6.0+. +This chart is tested with k8s 1.21+ and helm 3.8.0+. + +# NOTICE: Future Deprecation + +We have plans in the very near future to deprecate this chart in favor of a [new git repo](https://github.com/mastodon/helm-charts), which has proper helm repository support (e.g. `helm repo add`), and will contain multiple charts, both for mastodon and for supplementary components that we make use of. + +We still encourage suggestions and PRs to help make this chart better, and this repository will remain available after the new charts are ready to give users time to migrate. However, we will not be approving large PRs, or PRs that change fundamental chart functions, as those changes should be directed to the new charts. + +Please see the pinned [GitHub issue](https://github.com/mastodon/chart/issues/129) for more info & discussion. # Configuration @@ -64,57 +72,3 @@ Sidekiq deployments, it’s possible they will occur in the wrong order. After upgrading Mastodon versions, it may sometimes be necessary to manually delete the Rails and Sidekiq pods so that they are recreated against the latest migration. - -# Upgrades in 2.1.0 - -## ingressClassName and tls-acme changes -The annotations previously defaulting to nginx have been removed and support - for ingressClassName has been added. -```yaml -ingress: - annotations: - kubernetes.io/ingress.class: nginx - kubernetes.io/tls-acme: "true" -``` - -To restore the old functionality simply add the above snippet to your `values.yaml`, -but the recommendation is to replace these with `ingress.ingressClassName` and use -cert-manager's issuer/cluster-issuer instead of tls-acme. -If you're uncertain about your current setup leave `ingressClassName` empty and add -`kubernetes.io/tls-acme` to `ingress.annotations` in your `values.yaml`. - -# Upgrades in 2.0.0 - -## Fixed labels -Because of the changes in [#19706](https://github.com/mastodon/mastodon/pull/19706) the upgrade may fail with the following error: -```Error: UPGRADE FAILED: cannot patch "mastodon-sidekiq"``` - -If you want an easy upgrade and you're comfortable with some downtime then -simply delete the -sidekiq, -web, and -streaming Deployments manually. - -If you require a no-downtime upgrade then: -1. run `helm template` instead of `helm upgrade` -2. Copy the new -web and -streaming services into `services.yml` -3. Copy the new -web and -streaming deployments into `deployments.yml` -4. Append -temp to the name of each deployment in `deployments.yml` -5. `kubectl apply -f deployments.yml` then wait until all pods are ready -6. `kubectl apply -f services.yml` -7. Delete the old -sidekiq, -web, and -streaming deployments manually -8. `helm upgrade` like normal -9. `kubectl delete -f deployments.yml` to clear out the temporary deployments - -## PostgreSQL passwords -If you've previously installed the chart and you're having problems with -postgres not accepting your password then make sure to set `username` to -`postgres` and `password` and `postgresPassword` to the same passwords. -```yaml -postgresql: - auth: - username: postgres - password: - postgresPassword: -``` - -And make sure to set `password` to the same value as `postgres-password` -in your `mastodon-postgresql` secret: -```kubectl edit secret mastodon-postgresql``` \ No newline at end of file diff --git a/dev-values.yaml b/dev-values.yaml index b3a963e..18b4095 100644 --- a/dev-values.yaml +++ b/dev-values.yaml @@ -7,6 +7,11 @@ mastodon: vapid: private_key: dummy-vapid-private_key public_key: dummy-vapid-public_key + activeRecordEncryption: + primaryKey: dummy-are-primary_key + deterministicKey: dummy-are-deterministic_key + keyDerivationSalt: dummy-are-key_derivation_salt + # ref: https://github.com/bitnami/charts/tree/main/bitnami/redis#parameters redis: diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 2c50146..81872f9 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -106,7 +106,7 @@ Get the mastodon secret. {{- if .Values.mastodon.secrets.existingSecret }} {{- printf "%s" (tpl .Values.mastodon.secrets.existingSecret $) -}} {{- else -}} - {{- printf "%s" (include "common.names.fullname" .) -}} + {{- printf "%s" (include "mastodon.fullname" .) -}} {{- end -}} {{- end -}} @@ -117,7 +117,7 @@ Get the smtp secret. {{- if .Values.mastodon.smtp.existingSecret }} {{- printf "%s" (tpl .Values.mastodon.smtp.existingSecret $) -}} {{- else -}} - {{- printf "%s-smtp" (include "common.names.fullname" .) -}} + {{- printf "%s-smtp" (include "mastodon.fullname" .) -}} {{- end -}} {{- end -}} @@ -130,7 +130,7 @@ Get the postgresql secret. {{- else if .Values.postgresql.enabled -}} {{- printf "%s-postgresql" (tpl .Release.Name $) -}} {{- else -}} - {{- printf "%s" (include "common.names.fullname" .) -}} + {{- printf "%s" (include "mastodon.fullname" .) -}} {{- end -}} {{- end -}} diff --git a/templates/configmap-env.yaml b/templates/configmap-env.yaml index a4d4170..526e29a 100644 --- a/templates/configmap-env.yaml +++ b/templates/configmap-env.yaml @@ -87,6 +87,9 @@ data: {{- with .Values.mastodon.s3.multipart_threshold }} S3_MULTIPART_THRESHOLD: "{{ . }}" {{- end }} + {{- with .Values.mastodon.s3.override_path_style }} + S3_OVERRIDE_PATH_STYLE: "{{ . }}" + {{- end }} {{- end }} {{- with .Values.mastodon.smtp.auth_method }} SMTP_AUTH_METHOD: {{ . }} diff --git a/templates/deployment-sidekiq.yaml b/templates/deployment-sidekiq.yaml index 8cae4f3..b906149 100644 --- a/templates/deployment-sidekiq.yaml +++ b/templates/deployment-sidekiq.yaml @@ -22,7 +22,9 @@ spec: type: Recreate {{- end }} replicas: {{ .replicas }} - revisionHistoryLimit: 2 + {{- if (ne (toString $context.Values.mastodon.revisionHistoryLimit) "") }} + revisionHistoryLimit: {{ $context.Values.mastodon.revisionHistoryLimit }} + {{- end }} selector: matchLabels: {{- include "mastodon.selectorLabels" $context | nindent 6 }} @@ -36,7 +38,7 @@ 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 }} @@ -100,6 +102,10 @@ spec: name: {{ include "mastodon.fullname" $context }}-env - secretRef: name: {{ template "mastodon.secretName" $context }} + {{- if $context.Values.mastodon.extraEnvFrom }} + - configMapRef: + name: {{ $context.Values.mastodon.extraEnvFrom }} + {{- end}} env: - name: "DB_PASS" valueFrom: diff --git a/templates/deployment-streaming.yaml b/templates/deployment-streaming.yaml index 1e4acaa..8d66361 100644 --- a/templates/deployment-streaming.yaml +++ b/templates/deployment-streaming.yaml @@ -10,7 +10,9 @@ metadata: {{- end }} spec: replicas: {{ .Values.mastodon.streaming.replicas }} - revisionHistoryLimit: 2 + {{- if (ne (toString .Values.mastodon.revisionHistoryLimit) "") }} + revisionHistoryLimit: {{ .Values.mastodon.revisionHistoryLimit }} + {{- end }} selector: matchLabels: {{- include "mastodon.selectorLabels" . | nindent 6 }} @@ -37,6 +39,16 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.mastodon.streaming.extraCerts }} + {{- $name := .name | default "extra-certs" }} + volumes: + - name: {{ $name }} + secret: + secretName: {{ .existingSecret }} + items: + - key: ca.crt + path: trusted-ca.crt + {{- end }} containers: - name: {{ .Chart.Name }}-streaming {{- with (default .Values.securityContext .Values.mastodon.streaming.securityContext) }} @@ -48,10 +60,32 @@ spec: command: - node - ./streaming + {{- with .Values.mastodon.streaming.extraCerts }} + {{- $name := .name | default "extra-certs" }} + volumeMounts: + - name: {{ $name }} + mountPath: "/usr/local/share/ca-certificates" + {{- end }} envFrom: - configMapRef: name: {{ include "mastodon.fullname" . }}-env + {{- if .Values.mastodon.extraEnvFrom }} + - configMapRef: + name: {{ .Values.mastodon.extraEnvFrom }} + {{- end}} env: + {{- with .Values.mastodon.streaming.extraCerts }} + - name: "NODE_EXTRA_CA_CERTS" + value: "/usr/local/share/ca-certificates/trusted-ca.crt" + {{- with .sslMode }} + - name: "DB_SSLMODE" + value: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.postgresql.postgresqlReplicaHostname }} + - name: "DB_HOST" + value: {{ . }} + {{- end }} - name: "DB_PASS" valueFrom: secretKeyRef: diff --git a/templates/deployment-web.yaml b/templates/deployment-web.yaml index b8e8533..b1bb0b8 100644 --- a/templates/deployment-web.yaml +++ b/templates/deployment-web.yaml @@ -10,7 +10,9 @@ metadata: {{- end }} spec: replicas: {{ .Values.mastodon.web.replicas }} - revisionHistoryLimit: 2 + {{- if (ne (toString .Values.mastodon.revisionHistoryLimit) "") }} + revisionHistoryLimit: {{ .Values.mastodon.revisionHistoryLimit }} + {{- end }} selector: matchLabels: {{- include "mastodon.selectorLabels" . | nindent 6 }} @@ -77,6 +79,10 @@ spec: name: {{ include "mastodon.fullname" . }}-env - secretRef: name: {{ template "mastodon.secretName" . }} + {{- if .Values.mastodon.extraEnvFrom }} + - configMapRef: + name: {{ .Values.mastodon.extraEnvFrom }} + {{- end}} env: - name: "DB_PASS" valueFrom: diff --git a/templates/secret-smtp.yaml b/templates/secret-smtp.yaml index 98b15f3..893ecf7 100644 --- a/templates/secret-smtp.yaml +++ b/templates/secret-smtp.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Secret metadata: - name: {{ printf "%s-smtp" (include "common.names.fullname" .) }} + name: {{ printf "%s-smtp" (include "mastodon.fullname" .) }} labels: {{- include "mastodon.labels" . | nindent 4 }} type: Opaque diff --git a/templates/secrets.yaml b/templates/secrets.yaml index d1776ac..0eec2ab 100644 --- a/templates/secrets.yaml +++ b/templates/secrets.yaml @@ -34,6 +34,21 @@ data: {{- else }} VAPID_PUBLIC_KEY: {{ required "vapid.public_key is required" .Values.mastodon.secrets.vapid.public_key }} {{- end }} + {{- if not (empty .Values.mastodon.secrets.activeRecordEncryption.primaryKey) }} + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: "{{ .Values.mastodon.secrets.activeRecordEncryption.primaryKey | b64enc }}" + {{- else }} + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: {{ required "activeRecordEncryption.primaryKey is required" .Values.mastodon.secrets.activeRecordEncryption.primaryKey }} + {{- end }} + {{- if not (empty .Values.mastodon.secrets.activeRecordEncryption.deterministicKey) }} + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: "{{ .Values.mastodon.secrets.activeRecordEncryption.deterministicKey | b64enc }}" + {{- else }} + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: {{ required "activeRecordEncryption.deterministicKey is required" .Values.mastodon.secrets.activeRecordEncryption.deterministicKey }} + {{- end }} + {{- if not (empty .Values.mastodon.secrets.activeRecordEncryption.keyDerivationSalt) }} + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: "{{ .Values.mastodon.secrets.activeRecordEncryption.keyDerivationSalt | b64enc }}" + {{- else }} + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: {{ required "activeRecordEncryption.keyDerivationSalt is required" .Values.mastodon.secrets.activeRecordEncryption.keyDerivationSalt }} + {{- end }} {{- end }} {{- if not .Values.postgresql.enabled }} {{- if not .Values.postgresql.auth.existingSecret }} diff --git a/values.yaml b/values.yaml index e766afc..bd560bc 100644 --- a/values.yaml +++ b/values.yaml @@ -6,7 +6,7 @@ image: # built from the most recent commit # # tag: latest - tag: "v4.2.5" + tag: "v4.2.8" # use `Always` when using `latest` tag pullPolicy: IfNotPresent @@ -48,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: @@ -82,6 +82,8 @@ mastodon: # multipart_threshold then a multi part session is automatically started # and the data is sent up in chunks. Defaults to 16777216 (16MB). multipart_threshold: "" + # -- Set this to true if the storage provider uses domain style 'bucket.endpoint' naming + # override_path_style: "true" deepl: enabled: false plan: @@ -101,10 +103,25 @@ mastodon: vapid: private_key: "" public_key: "" + activeRecordEncryption: + primaryKey: "" + deterministicKey: "" + keyDerivationSalt: "" # -- you can also specify the name of an existing Secret - # with keys SECRET_KEY_BASE and OTP_SECRET and - # VAPID_PRIVATE_KEY and VAPID_PUBLIC_KEY + # with keys: + # - SECRET_KEY_BASE + # - OTP_SECRET + # - VAPID_PRIVATE_KEY + # - VAPID_PUBLIC_KEY + # - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY + # - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY + # - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT existingSecret: "" + + # -- The number of old revisions to keep for each Deployment in Kubernetes. + # See https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy + revisionHistoryLimit: 2 + sidekiq: # -- Pod security context for all Sidekiq Pods, overwrites .Values.podSecurityContext podSecurityContext: {} @@ -217,6 +234,14 @@ mastodon: # requests: # cpu: 250m # memory: 128Mi + # -- Self-signed certificate(s) the (Node.js) needs to trust to connect to e.g. the database + extraCerts: {} + # -- Secret containing a key "ca.crt" holding one or more root certificates in PEM format + # existingSecret: + # -- Optional volume name for mounting the .crt file, defaults to "extra-certs" + # name: + # -- Optional sslMode setting. See nodejs's SSL_MODE. Consider "no-verify" + # sslMode: web: port: 3000 # -- Number of Web Pods running @@ -278,9 +303,16 @@ mastodon: # Sets the PREPARED_STATEMENTS environment variable: https://docs.joinmastodon.org/admin/config/#prepared_statements preparedStatements: true - # Additional env vars defined in all pods + + # 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: