redis
elasticsearch
+# ignore Helm lockfile, dependency charts, and local values file
+chart/Chart.lock
+chart/charts/*.tgz
+chart/values.yaml
+
# Ignore Apple files
.DS_Store
--- /dev/null
+# 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/
--- /dev/null
+apiVersion: v2
+name: mastodon
+description: Mastodon is a free, open-source social network server based on ActivityPub.
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# 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.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.1.0
+
+# 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: 3.1.4
+
+dependencies:
+ - name: elasticsearch
+ version: "12.x.x"
+ repository: https://charts.bitnami.com/bitnami
+ condition: elasticsearch.enabled
+ - name: postgresql
+ version: "8.x.x"
+ repository: https://charts.bitnami.com/bitnami
+ - name: redis
+ version: "10.x.x"
+ repository: https://charts.bitnami.com/bitnami
--- /dev/null
+# Introduction
+
+This is a [Helm](https://helm.sh/) chart for installing Mastodon into a
+Kubernetes cluster. The basic usage is:
+
+```
+cp values.yaml.template values.yaml
+edit values.yaml # configure required settings
+helm dep update
+helm upgrade --install my-mastodon ./
+```
+
+This chart has been tested on Helm 3.0.1 and above.
+
+# Configuration
+
+The variables that _must_ be configured are:
+
+- `ingress.hostname`; even if you aren’t using an Ingress, this value is used to
+ set `LOCAL_DOMAIN`.
+
+- password and keys in the `secrets`, `postgresql`, and `redis` groups; if
+ left blank, some of those values will be autogenerated, but will not persist
+ across upgrades.
+
+- SMTP settings for your mailer in the `smtp` group.
+
+# Missing features
+
+Currently this chart does _not_ support:
+
+- Hidden services
+- S3/Minio/GCS
+- Single Sign-On
+- Swift
+- configurations using `WEB_DOMAIN`
+
+# Upgrading
+
+Because database migrations are managed as a Job separate from the Rails and
+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.
--- /dev/null
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+ {{- range .paths }}
+ http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+ {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+ export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "mastodon.fullname" . }})
+ export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+ echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+ NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+ You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "mastodon.fullname" . }}'
+ export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mastodon.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+ echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+ export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "mastodon.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+ echo "Visit http://127.0.0.1:8080 to use your application"
+ kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
--- /dev/null
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "mastodon.name" -}}
+{{- default .Chart.Name .Values.nameOverride | 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).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "mastodon.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "mastodon.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "mastodon.labels" -}}
+helm.sh/chart: {{ include "mastodon.chart" . }}
+{{ include "mastodon.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "mastodon.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "mastodon.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "mastodon.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "mastodon.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create a default fully qualified name for dependent services.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+*/}}
+{{- define "mastodon.elasticsearch.fullname" -}}
+{{- printf "%s-%s" .Release.Name "elasticsearch" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "mastodon.redis.fullname" -}}
+{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "mastodon.postgresql.fullname" -}}
+{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
--- /dev/null
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "mastodon.fullname" . }}-env
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+data:
+ DB_HOST: {{ template "mastodon.postgresql.fullname" . }}
+ DB_NAME: {{ .Values.postgresql.postgresqlDatabase }}
+ DB_POOL: {{ .Values.application.sidekiq.concurrency | quote }}
+ DB_PORT: "5432"
+ DB_USER: {{ .Values.postgresql.postgresqlUsername }}
+ DEFAULT_LOCALE: {{ .Values.locale }}
+ {{- if .Values.elasticsearch.enabled }}
+ ES_ENABLED: "true"
+ ES_HOST: {{ template "mastodon.elasticsearch.fullname" . }}-master
+ ES_PORT: "9200"
+ {{- end }}
+ LOCAL_DOMAIN: {{ .Values.ingress.hostname }}
+ # https://devcenter.heroku.com/articles/tuning-glibc-memory-behavior
+ MALLOC_ARENA_MAX: "2"
+ NODE_ENV: "production"
+ RAILS_ENV: "production"
+ REDIS_HOST: {{ template "mastodon.redis.fullname" . }}-master
+ REDIS_PORT: "6379"
+ {{- if .Values.smtp.auth_method }}
+ SMTP_AUTH_METHOD: {{ .Values.smtp.auth_method }}
+ {{- end }}
+ {{- if .Values.smtp.ca_file }}
+ SMTP_CA_FILE: {{ .Values.smtp.ca_file }}
+ {{- end }}
+ {{- if .Values.smtp.delivery_method }}
+ SMTP_DELIVERY_METHOD: {{ .Values.smtp.delivery_method }}
+ {{- end }}
+ {{- if .Values.smtp.domain }}
+ SMTP_DOMAIN: {{ .Values.smtp.domain }}
+ {{- end }}
+ {{- if .Values.smtp.enable_starttls_auto }}
+ SMTP_ENABLE_STARTTLS_AUTO: {{ .Values.smtp.enable_starttls_auto | quote }}
+ {{- end }}
+ {{- if .Values.smtp.from_address }}
+ SMTP_FROM_ADDRESS: {{ .Values.smtp.from_address }}
+ {{- end }}
+ {{- if .Values.smtp.login }}
+ SMTP_LOGIN: {{ .Values.smtp.login }}
+ {{- end }}
+ {{- if .Values.smtp.openssl_verify_mode }}
+ SMTP_OPENSSL_VERIFY_MODE: {{ .Values.smtp.openssl_verify_mode }}
+ {{- end }}
+ {{- if .Values.smtp.password }}
+ SMTP_PASSWORD: {{ .Values.smtp.password }}
+ {{- end }}
+ {{- if .Values.smtp.port }}
+ SMTP_PORT: {{ .Values.smtp.port | quote }}
+ {{- end }}
+ {{- if .Values.smtp.reply_to }}
+ SMTP_REPLY_TO: {{ .Values.smtp.reply_to }}
+ {{- end }}
+ {{- if .Values.smtp.server }}
+ SMTP_SERVER: {{ .Values.smtp.server }}
+ {{- end }}
+ {{- if .Values.smtp.tls }}
+ SMTP_TLS: {{ .Values.smtp.tls | quote }}
+ {{- end }}
+ STREAMING_CLUSTER_NUM: {{ .Values.application.streaming.workers | quote }}
--- /dev/null
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "mastodon.fullname" . }}-sidekiq
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+{{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicaCount }}
+{{- end }}
+ selector:
+ matchLabels:
+ {{- include "mastodon.selectorLabels" . | nindent 6 }}
+ component: rails
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ # roll the pods to pick up any db migrations
+ rollme: {{ randAlphaNum 5 | quote }}
+ {{- end }}
+ labels:
+ {{- include "mastodon.selectorLabels" . | nindent 8 }}
+ component: rails
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "mastodon.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ # ensure we run on the same node as the other rails components; only
+ # required when using PVCs that are ReadWriteOnce
+ {{- if or (eq "ReadWriteOnce" .Values.persistence.assets.accessMode) (eq "ReadWriteOnce" .Values.persistence.system.accessMode) }}
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: component
+ operator: In
+ values:
+ - rails
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bundle
+ - exec
+ - sidekiq
+ - -c
+ - {{ .Values.application.sidekiq.concurrency | quote }}
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
--- /dev/null
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "mastodon.fullname" . }}-streaming
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+{{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicaCount }}
+{{- end }}
+ selector:
+ matchLabels:
+ {{- include "mastodon.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "mastodon.selectorLabels" . | nindent 8 }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "mastodon.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - node
+ - ./streaming
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.streaming.port | quote }}
+ ports:
+ - name: streaming
+ containerPort: {{ .Values.application.streaming.port }}
+ protocol: TCP
+ livenessProbe:
+ httpGet:
+ path: /api/v1/streaming/health
+ port: streaming
+ readinessProbe:
+ httpGet:
+ path: /api/v1/streaming/health
+ port: streaming
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
--- /dev/null
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "mastodon.fullname" . }}-web
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+{{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicaCount }}
+{{- end }}
+ selector:
+ matchLabels:
+ {{- include "mastodon.selectorLabels" . | nindent 6 }}
+ component: rails
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ # roll the pods to pick up any db migrations
+ rollme: {{ randAlphaNum 5 | quote }}
+ {{- end }}
+ labels:
+ {{- include "mastodon.selectorLabels" . | nindent 8 }}
+ component: rails
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "mastodon.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bundle
+ - exec
+ - puma
+ - -C
+ - config/puma.rb
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.web.port | quote }}
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
+ ports:
+ - name: http
+ containerPort: {{ .Values.application.web.port }}
+ protocol: TCP
+ livenessProbe:
+ httpGet:
+ path: /health
+ port: http
+ readinessProbe:
+ httpGet:
+ path: /health
+ port: http
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
--- /dev/null
+{{- if .Values.autoscaling.enabled }}
+apiVersion: autoscaling/v2beta1
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "mastodon.fullname" . }}
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "mastodon.fullname" . }}
+ minReplicas: {{ .Values.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+{{- end }}
--- /dev/null
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "mastodon.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+ name: {{ $fullName }}
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ - host: {{ .Values.ingress.hostname | quote }}
+ http:
+ paths:
+ - path: '/'
+ backend:
+ serviceName: {{ $fullName }}-web
+ servicePort: {{ $svcPort }}
+ - path: '/api/v1/streaming'
+ backend:
+ serviceName: {{ $fullName }}-streaming
+ servicePort: {{ .Values.application.streaming.port }}
+{{- end }}
--- /dev/null
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "mastodon.fullname" . }}-assets-precompile
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": post-install
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+ "helm.sh/hook-weight": "-2"
+spec:
+ template:
+ metadata:
+ name: {{ include "mastodon.fullname" . }}-assets-precompile
+ spec:
+ restartPolicy: Never
+ # ensure we run on the same node as the other rails components; only
+ # required when using PVCs that are ReadWriteOnce
+ {{- if or (eq "ReadWriteOnce" .Values.persistence.assets.accessMode) (eq "ReadWriteOnce" .Values.persistence.system.accessMode) }}
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: component
+ operator: In
+ values:
+ - rails
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ include "mastodon.fullname" . }}-assets-precompile
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bash
+ - -c
+ - |
+ bundle exec rake assets:precompile && yarn cache clean
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.web.port | quote }}
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
--- /dev/null
+{{- if .Values.elasticsearch.enabled }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "mastodon.fullname" . }}-chewy-upgrade
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": post-install
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+ "helm.sh/hook-weight": "-1"
+spec:
+ template:
+ metadata:
+ name: {{ include "mastodon.fullname" . }}-chewy-upgrade
+ spec:
+ restartPolicy: Never
+ # ensure we run on the same node as the other rails components; only
+ # required when using PVCs that are ReadWriteOnce
+ {{- if or (eq "ReadWriteOnce" .Values.persistence.assets.accessMode) (eq "ReadWriteOnce" .Values.persistence.system.accessMode) }}
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: component
+ operator: In
+ values:
+ - rails
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ include "mastodon.fullname" . }}-chewy-setup
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bundle
+ - exec
+ - rake
+ - chewy:upgrade
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.web.port | quote }}
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
+{{- end }}
--- /dev/null
+{{- if .Values.createAdmin.enabled }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "mastodon.fullname" . }}-create-admin
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": post-install
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+ "helm.sh/hook-weight": "-1"
+spec:
+ template:
+ metadata:
+ name: {{ include "mastodon.fullname" . }}-create-admin
+ spec:
+ restartPolicy: Never
+ # ensure we run on the same node as the other rails components; only
+ # required when using PVCs that are ReadWriteOnce
+ {{- if or (eq "ReadWriteOnce" .Values.persistence.assets.accessMode) (eq "ReadWriteOnce" .Values.persistence.system.accessMode) }}
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: component
+ operator: In
+ values:
+ - rails
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ include "mastodon.fullname" . }}-create-admin
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bin/tootctl
+ - accounts
+ - create
+ - {{ .Values.createAdmin.username }}
+ - --email
+ - {{ .Values.createAdmin.email }}
+ - --confirmed
+ - --role
+ - admin
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.web.port | quote }}
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
+{{- end }}
--- /dev/null
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "mastodon.fullname" . }}-db-migrate
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": post-install,pre-upgrade
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+ "helm.sh/hook-weight": "-2"
+spec:
+ template:
+ metadata:
+ name: {{ include "mastodon.fullname" . }}-db-migrate
+ spec:
+ restartPolicy: Never
+ # ensure we run on the same node as the other rails components; only
+ # required when using PVCs that are ReadWriteOnce
+ {{- if or (eq "ReadWriteOnce" .Values.persistence.assets.accessMode) (eq "ReadWriteOnce" .Values.persistence.system.accessMode) }}
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: component
+ operator: In
+ values:
+ - rails
+ topologyKey: kubernetes.io/hostname
+ {{- end }}
+ volumes:
+ - name: assets
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-assets
+ - name: system
+ persistentVolumeClaim:
+ claimName: {{ template "mastodon.fullname" . }}-system
+ containers:
+ - name: {{ include "mastodon.fullname" . }}-db-migrate
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - bundle
+ - exec
+ - rake
+ - db:migrate
+ envFrom:
+ - configMapRef:
+ name: {{ include "mastodon.fullname" . }}-env
+ - secretRef:
+ name: {{ template "mastodon.fullname" . }}
+ env:
+ - name: "DB_PASS"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgresql-password
+ - name: "REDIS_PASSWORD"
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-redis
+ key: redis-password
+ - name: "PORT"
+ value: {{ .Values.application.web.port | quote }}
+ volumeMounts:
+ - name: assets
+ mountPath: /opt/mastodon/public/assets
+ - name: system
+ mountPath: /opt/mastodon/public/system
--- /dev/null
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ template "mastodon.fullname" . }}-assets
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.system.accessMode }}
+ resources:
+ {{- toYaml .Values.persistence.assets.resources | nindent 4}}
+ storageClassName: {{ .Values.persistence.assets.storageClassName }}
--- /dev/null
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ template "mastodon.fullname" . }}-system
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.system.accessMode }}
+ resources:
+ {{- toYaml .Values.persistence.system.resources | nindent 4}}
+ storageClassName: {{ .Values.persistence.system.storageClassName }}
--- /dev/null
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ template "mastodon.fullname" . }}
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+type: Opaque
+data:
+ {{- if not (empty .Values.secrets.secret_key_base) }}
+ SECRET_KEY_BASE: "{{ .Values.secrets.secret_key_base | b64enc }}"
+ {{- else }}
+ SECRET_KEY_BASE: {{ required "secret_key_base is required" .Values.secrets.secret_key_base }}
+ {{- end }}
+ {{- if not (empty .Values.secrets.otp_secret) }}
+ OTP_SECRET: "{{ .Values.secrets.otp_secret | b64enc }}"
+ {{- else }}
+ OTP_SECRET: {{ required "otp_secret is required" .Values.secrets.otp_secret }}
+ {{- end }}
+ {{- if not (empty .Values.secrets.vapid.private_key) }}
+ VAPID_PRIVATE_KEY: "{{ .Values.secrets.vapid.private_key | b64enc }}"
+ {{- else }}
+ VAPID_PRIVATE_KEY: {{ required "vapid.private_key is required" .Values.secrets.vapid.private_key }}
+ {{- end }}
+ {{- if not (empty .Values.secrets.vapid.public_key) }}
+ VAPID_PUBLIC_KEY: "{{ .Values.secrets.vapid.public_key | b64enc }}"
+ {{- else }}
+ VAPID_PUBLIC_KEY: {{ required "vapid.public_key is required" .Values.secrets.vapid.public_key }}
+ {{- end }}
--- /dev/null
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "mastodon.fullname" . }}-streaming
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.application.streaming.port }}
+ targetPort: streaming
+ protocol: TCP
+ name: streaming
+ selector:
+ {{- include "mastodon.selectorLabels" . | nindent 4 }}
--- /dev/null
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "mastodon.fullname" . }}-web
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "mastodon.selectorLabels" . | nindent 4 }}
--- /dev/null
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "mastodon.serviceAccountName" . }}
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
--- /dev/null
+apiVersion: v1
+kind: Pod
+metadata:
+ name: "{{ include "mastodon.fullname" . }}-test-connection"
+ labels:
+ {{- include "mastodon.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": test-success
+spec:
+ containers:
+ - name: wget
+ image: busybox
+ command: ['wget']
+ args: ['{{ include "mastodon.fullname" . }}:{{ .Values.service.port }}']
+ restartPolicy: Never
--- /dev/null
+replicaCount: 1
+
+image:
+ repository: tootsuite/mastodon
+ pullPolicy: Always
+ # https://hub.docker.com/r/tootsuite/mastodon/tags
+ tag: v3.1.4
+ # alternatively, use `latest` for the latest release or `edge` for the image
+ # built from the most recent commit
+ #
+ # tag: latest
+
+ingress:
+ enabled: false
+ annotations:
+ kubernetes.io/ingress.class: nginx
+ kubernetes.io/tls-acme: "true"
+ # cert-manager.io/cluster-issuer: "letsencrypt"
+ # this value is used for LOCAL_DOMAIN
+ hostname: mastodon.local
+ tls:
+ - secretName: mastodon-tls
+ hosts:
+ - mastodon.local
+
+# create an initial administrator user; the password is autogenerated and will
+# have to be reset
+createAdmin:
+ enabled: false
+ username: not_gargron
+ email: not@example.com
+
+# available locales: https://github.com/tootsuite/mastodon/blob/master/config/application.rb#L43
+locale: en
+
+application:
+ web:
+ port: 3000
+ streaming:
+ 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
+ # the pod by k8s
+ workers: 1
+ sidekiq:
+ concurrency: 25
+
+# these must be set manually; autogenerated keys are rotated on each upgrade
+secrets:
+ secret_key_base: ""
+ otp_secret: ""
+ vapid:
+ private_key: ""
+ public_key: ""
+
+smtp:
+ auth_method: plain
+ ca_file:
+ delivery_method: smtp
+ domain:
+ enable_starttls_auto: true
+ from_address: notifications@example.com
+ login:
+ openssl_verify_mode: peer
+ password:
+ port: 587
+ reply_to:
+ server: smtp.mailgun.org
+ tls: false
+
+# https://github.com/bitnami/charts/tree/master/bitnami/elasticsearch#parameters
+elasticsearch:
+ # `false` will disable full-text search
+ #
+ # 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/)
+ enabled: true
+ # may be removed once https://github.com/tootsuite/mastodon/pull/13828 is part
+ # of a tagged release
+ image:
+ tag: 6
+
+# https://github.com/bitnami/charts/tree/master/bitnami/postgresql#parameters
+postgresql:
+ postgresqlDatabase: mastodon_production
+ # you must set a password; the password generated by the postgresql chart will
+ # be rotated on each upgrade:
+ # https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrade
+ postgresqlPassword: ""
+ postgresqlUsername: postgres
+
+# https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters
+redis:
+ # you must set a password; the password generated by the redis chart will be
+ # rotated on each upgrade:
+ password: ""
+
+persistence:
+ assets:
+ # ReadWriteOnce is more widely supported than ReadWriteMany, but limits
+ # scalability, since it requires the Rails and Sidekiq pods to run on the
+ # same node.
+ accessMode: ReadWriteOnce
+ resources:
+ requests:
+ storage: 100Gi
+ system:
+ accessMode: ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+
+service:
+ type: ClusterIP
+ port: 80
+
+# https://github.com/tootsuite/mastodon/blob/master/Dockerfile#L88
+#
+# if you manually change the UID/GID environment variables, ensure these values
+# match:
+podSecurityContext:
+ runAsUser: 991
+ runAsGroup: 991
+ fsGroup: 991
+
+securityContext: {}
+
+serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+podAnnotations: {}
+
+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:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+autoscaling:
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 100
+ targetCPUUtilizationPercentage: 80
+ # targetMemoryUtilizationPercentage: 80
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}