* add Helm chart known issues/future work: - SSO is unsupported - S3/Minio/GCS is unsupported - Swift is unsupported - WEB_DOMAIN is unsupported - Tor is unsupported * helm: clarify how LOCAL_DOMAIN is set * helm: add chart description * helm: make DB_POOL and Sidekiq concurrency configurable * helm: only enforce pod affinity when using ReadWriteOnce * helm: clarify compatibility * helm: clean up application variables * helm: add job to create initial adminmaster
@ -0,0 +1,23 @@ | |||
# Patterns to ignore when building packages. | |||
# This supports shell glob matching, relative path matching, and | |||
# negation (prefixed with !). Only one pattern per line. | |||
.DS_Store | |||
# Common VCS dirs | |||
.git/ | |||
.gitignore | |||
.bzr/ | |||
.bzrignore | |||
.hg/ | |||
.hgignore | |||
.svn/ | |||
# Common backup files | |||
*.swp | |||
*.bak | |||
*.tmp | |||
*.orig | |||
*~ | |||
# Various IDEs | |||
.project | |||
.idea/ | |||
*.tmproj | |||
.vscode/ |
@ -0,0 +1,35 @@ | |||
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 |
@ -0,0 +1,44 @@ | |||
# 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. |
@ -0,0 +1,21 @@ | |||
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 }} |
@ -0,0 +1,79 @@ | |||
{{/* 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 -}} |
@ -0,0 +1,65 @@ | |||
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 }} |
@ -0,0 +1,97 @@ | |||
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 }} |
@ -0,0 +1,80 @@ | |||
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 }} |
@ -0,0 +1,101 @@ | |||
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 }} |
@ -0,0 +1,28 @@ | |||
{{- 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 }} |
@ -0,0 +1,41 @@ | |||
{{- 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 }} |
@ -0,0 +1,69 @@ | |||
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 |
@ -0,0 +1,71 @@ | |||
{{- 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 }} |
@ -0,0 +1,76 @@ | |||
{{- 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 }} | |||
- {{ .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 }} |
@ -0,0 +1,69 @@ | |||
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 |
@ -0,0 +1,13 @@ | |||
--- | |||
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 }} |
@ -0,0 +1,13 @@ | |||
--- | |||
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 }} |
@ -0,0 +1,28 @@ | |||
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 }} |
@ -0,0 +1,15 @@ | |||
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 }} |
@ -0,0 +1,15 @@ | |||
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 }} |
@ -0,0 +1,12 @@ | |||
{{- 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 }} |
@ -0,0 +1,15 @@ | |||
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 |
@ -0,0 +1,163 @@ | |||
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: {} |