├── .gitignore ├── README.md └── deploy ├── config.yml ├── external-dns.yml ├── ingress.yml.template ├── postgres-deployment.yml ├── postgres-service.yml ├── postgres-volume-claim.yml ├── redis-deployment.yml ├── redis-service.yml ├── redis-volume-claim.yml ├── secret.yml.template ├── sidekiq-deployment.yml ├── streaming-deployment.yml ├── streaming-service.yml ├── web-deployment.yml └── web-service.yml /.gitignore: -------------------------------------------------------------------------------- 1 | deploy/secret.yml 2 | deploy/ingress.yml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | kube-mastodon 2 | ============= 3 | 4 | This repository contains everything you need to get a Mastodon server running on Mastodon 2.5.0. 5 | 6 | 7 | Upgrading from 2.4.2 8 | -------------------- 9 | 10 | Upgrade the checkout of this repo: 11 | 12 | ``` 13 | git pull origin master 14 | ``` 15 | 16 | Replace the new deployments: 17 | 18 | ``` 19 | kubectl replace -f deploy/web-deployment.yml 20 | kubectl replace -f deploy/streaming-deployment.yml 21 | kubectl replace -f deploy/sidekiq-deployment.yml 22 | ``` 23 | 24 | Wait a minute or so for these to redeploy... 25 | 26 | Now run a database upgrade by connecting to the new pod: 27 | 28 | ``` 29 | export MASTODON_POD=$(kubectl get pods -l app=mastodon-web -o jsonpath='{.items[0].metadata.name}') 30 | kubectl exec $MASTODON_POD -i -t -- bash -il 31 | ``` 32 | 33 | And once you're connected: 34 | 35 | ``` 36 | $ RAILS_ENV=production bundle exec rails db:migrate 37 | ``` 38 | 39 | You're all set - things should be upgraded now! 40 | 41 | 42 | Deployment 43 | ---------- 44 | 45 | Copy the template files to their proper places: 46 | 47 | ``` 48 | cp deploy/ingress.yml.template deploy/ingress.yml 49 | cp deploy/secret.yml.template deploy/secret.yml 50 | ``` 51 | 52 | Now fill in the proper values for those files. 53 | 54 | Then deploy everything else: 55 | 56 | ``` 57 | kubectl create -f deploy/config.yml 58 | kubectl create -f deploy/secret.yml 59 | 60 | kubectl create -f deploy/postgres-volume-claim.yml 61 | kubectl create -f deploy/postgres-deployment.yml 62 | kubectl create -f deploy/postgres-service.yml 63 | 64 | kubectl create -f deploy/redis-volume-claim.yml 65 | kubectl create -f deploy/redis-deployment.yml 66 | kubectl create -f deploy/redis-service.yml 67 | 68 | kubectl create -f deploy/web-deployment.yml 69 | kubectl create -f deploy/web-service.yml 70 | 71 | kubectl create -f deploy/streaming-deployment.yml 72 | kubectl create -f deploy/streaming-service.yml 73 | 74 | kubectl create -f deploy/sidekiq-deployment.yml 75 | 76 | kubectl create -f deploy/ingress.yml 77 | kubectl create -f deploy/external-dns.yml 78 | ``` 79 | 80 | Now look up the pod name for the web container: 81 | 82 | ``` 83 | kubectl get pods 84 | ``` 85 | 86 | Finally, connect to the web pod so we can set up the database 87 | (use the pod name from before): 88 | 89 | ``` 90 | export MASTODON_POD=$(kubectl get pods -l app=mastodon-web -o jsonpath='{.items[0].metadata.name}') 91 | kubectl exec $MASTODON_POD -i -t -- bash -il 92 | ``` 93 | 94 | Once you're connected, run this command to set up the db, 95 | but don't disconnect. 96 | 97 | ``` 98 | $ RAILS_ENV=production bundle exec rails db:migrate 99 | ``` 100 | 101 | Now in the same session, generate VAPID keys: 102 | ``` 103 | $ RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key 104 | ``` 105 | 106 | Finally update your secret with the VAPID keys, and replace the secret: 107 | ``` 108 | kubectl replace -f deploy/secret.yml 109 | ``` 110 | 111 | You may need to kill your streaming, sidekiq, and web pods to get the new env vars. -------------------------------------------------------------------------------- /deploy/config.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: mastodon 5 | data: 6 | REDIS_HOST: mastodon-redis 7 | REDIS_PORT: "6379" 8 | DB_HOST: mastodon-postgres 9 | DB_USER: mastodon 10 | DB_NAME: mastodon 11 | DB_PORT: "5432" 12 | LOCAL_HTTPS: "true" 13 | SMTP_AUTH_METHOD: plain 14 | SMTP_OPENSSL_VERIFY_MODE: peer 15 | SMTP_ENABLE_STARTTLS_AUTO: "true" 16 | S3_ENABLED: "true" 17 | #SINGLE_USER_MODE: "true" 18 | #EMAIL_DOMAIN_BLACKLIST: "example1.com|example2.de|etc" 19 | #EMAIL_DOMAIN_WHITELIST: "example1.com|example2.de|etc" 20 | #DEFAULT_LOCALE: de -------------------------------------------------------------------------------- /deploy/external-dns.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-external-dns 5 | spec: 6 | strategy: 7 | type: Recreate 8 | template: 9 | metadata: 10 | labels: 11 | app: mastodon-external-dns 12 | spec: 13 | containers: 14 | - name: external-dns 15 | image: registry.opensource.zalan.do/teapot/external-dns:latest 16 | args: 17 | - --source=ingress 18 | - --domain-filter=$(LOCAL_DOMAIN) 19 | - --provider=google 20 | - --registry=txt 21 | - --txt-owner-id=extdns 22 | env: 23 | - name: LOCAL_DOMAIN 24 | valueFrom: 25 | secretKeyRef: 26 | name: mastodon 27 | key: LOCAL_DOMAIN 28 | -------------------------------------------------------------------------------- /deploy/ingress.yml.template: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: mastodon 5 | annotations: 6 | kubernetes.io/tls-acme: "true" 7 | kubernetes.io/ingress.class: "nginx" 8 | nginx.ingress.kubernetes.io/force-ssl-redirect: "true" 9 | nginx.ingress.kubernetes.io/proxy-body-size: 64m 10 | spec: 11 | tls: 12 | - secretName: mastodon-cert 13 | hosts: 14 | - YOUR_DOMAIN_NAME_HERE 15 | backend: 16 | serviceName: mastodon-web 17 | servicePort: 3000 18 | rules: 19 | - host: YOUR_DOMAIN_NAME_HERE 20 | http: 21 | paths: 22 | - path: /api/v1/streaming 23 | backend: 24 | serviceName: mastodon-streaming 25 | servicePort: 4000 26 | - path: / 27 | backend: 28 | serviceName: mastodon-web 29 | servicePort: 3000 -------------------------------------------------------------------------------- /deploy/postgres-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-postgres 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: mastodon-postgres 11 | spec: 12 | volumes: 13 | - name: mastodon-postgres-data 14 | persistentVolumeClaim: 15 | claimName: mastodon-postgres 16 | containers: 17 | - name: postgres 18 | image: postgres:10.4 19 | ports: 20 | - containerPort: 5432 21 | env: 22 | - name: POSTGRES_DB 23 | valueFrom: 24 | configMapKeyRef: 25 | name: mastodon 26 | key: DB_NAME 27 | - name: POSTGRES_USER 28 | valueFrom: 29 | configMapKeyRef: 30 | name: mastodon 31 | key: DB_USER 32 | - name: POSTGRES_PASSWORD 33 | valueFrom: 34 | secretKeyRef: 35 | name: mastodon 36 | key: DB_PASS 37 | - name: PGDATA 38 | value: /var/lib/postgresql/data/pgdata 39 | volumeMounts: 40 | - name: mastodon-postgres-data 41 | mountPath: /var/lib/postgresql/data -------------------------------------------------------------------------------- /deploy/postgres-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mastodon-postgres 5 | namespace: default 6 | spec: 7 | type: NodePort 8 | ports: 9 | - name: psql 10 | port: 5432 11 | targetPort: 5432 12 | protocol: TCP 13 | selector: 14 | app: mastodon-postgres -------------------------------------------------------------------------------- /deploy/postgres-volume-claim.yml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: mastodon-postgres 5 | spec: 6 | storageClassName: fast 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 30Gi -------------------------------------------------------------------------------- /deploy/redis-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-redis 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: mastodon-redis 11 | spec: 12 | volumes: 13 | - name: mastodon-redis-data 14 | persistentVolumeClaim: 15 | claimName: mastodon-redis 16 | containers: 17 | - name: redis 18 | image: redis:4.0.10-alpine 19 | resources: 20 | requests: 21 | memory: 64Mi 22 | cpu: 50m 23 | ports: 24 | - containerPort: 6379 25 | volumeMounts: 26 | - name: mastodon-redis-data 27 | mountPath: /data -------------------------------------------------------------------------------- /deploy/redis-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mastodon-redis 5 | namespace: default 6 | spec: 7 | type: NodePort 8 | ports: 9 | - name: redis 10 | port: 6379 11 | targetPort: 6379 12 | protocol: TCP 13 | selector: 14 | app: mastodon-redis -------------------------------------------------------------------------------- /deploy/redis-volume-claim.yml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: mastodon-redis 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 30Gi -------------------------------------------------------------------------------- /deploy/secret.yml.template: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mastodon 5 | type: Opaque 6 | data: 7 | DB_PASS: YOUR DB PASS HERE (BASE64 ENCODED) 8 | PAPERCLIP_SECRET: YOUR PAPERCLIP SECRET HERE (BASE64 ENCODED) 9 | SECRET_KEY_BASE: YOUR SECRET KEY BASE HERE (BASE64 ENCODED) 10 | OTP_SECRET: YOUR OTP SECRET HERE (BASE64 ENCODED) 11 | LOCAL_DOMAIN: YOUR LOCAL DOMAIN HERE (BASE64 ENCODED) 12 | SMTP_SERVER: YOUR SMTP SERVER HERE (BASE64 ENCODED) 13 | SMTP_PORT: YOUR SMTP PORT HERE (BASE64 ENCODED) 14 | SMTP_LOGIN: YOUR SMTP LOGIN HERE (BASE64 ENCODED) 15 | SMTP_PASSWORD: YOUR SMTP PASSWORD HERE (BASE64 ENCODED) 16 | SMTP_FROM_ADDRESS: YOUR SMTP FROM ADDRESS HERE (BASE64 ENCODED) 17 | SMTP_DOMAIN: YOUR SMTP DOMAIN HERE (BASE64 ENCODED) 18 | S3_BUCKET: YOUR S3 BUCKET HERE (BASE64 ENCODED) 19 | AWS_ACCESS_KEY_ID: YOUR AWS ACCESS KEY ID HERE (BASE64 ENCODED) 20 | AWS_SECRET_ACCESS_KEY: YOUR AWS SECRET ACCESS KEY HERE (BASE64 ENCODED) 21 | S3_REGION: YOUR S3 REGION HERE (BASE64 ENCODED) 22 | S3_PROTOCOL: YOUR S3 PROTOCOL HERE (BASE64 ENCODED) 23 | S3_HOSTNAME: YOUR S3 HOSTNAME HERE s3-$S3_REGION.amazonaws.com (BASE64 ENCODED) 24 | VAPID_PRIVATE_KEY: YOUR VAPID PRIVATE KEY HERE (BASE64 ENCODED) 25 | VAPID_PUBLIC_KEY: YOUR VAPID PUBLIC KEY HERE (BASE64 ENCODED) -------------------------------------------------------------------------------- /deploy/sidekiq-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-sidekiq 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: mastodon-sidekiq 11 | spec: 12 | containers: 13 | - name: sidekiq 14 | image: tootsuite/mastodon:v2.5.0 15 | command: ["/usr/bin/env", "bash", "-c", "echo \"${CAFILE_RB}\" > config/initializers/cafile.rb && bundle exec rails assets:precompile && bundle exec sidekiq -q default -q mailers -q pull -q push"] 16 | env: 17 | - name: CAFILE_RB 18 | value: | 19 | Rails.application.configure do 20 | config.action_mailer.smtp_settings[:ca_file] = "/etc/ssl/certs/ca-certificates.crt" 21 | end 22 | envFrom: 23 | - configMapRef: 24 | name: mastodon 25 | - secretRef: 26 | name: mastodon 27 | resources: 28 | requests: 29 | memory: 128Mi 30 | cpu: 50m -------------------------------------------------------------------------------- /deploy/streaming-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-streaming 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: mastodon-streaming 11 | spec: 12 | containers: 13 | - name: streaming 14 | image: tootsuite/mastodon:v2.5.0 15 | command: ["yarn", "start"] 16 | ports: 17 | - name: streaming 18 | containerPort: 4000 19 | envFrom: 20 | - configMapRef: 21 | name: mastodon 22 | - secretRef: 23 | name: mastodon 24 | resources: 25 | requests: 26 | memory: 32Mi 27 | cpu: 25m -------------------------------------------------------------------------------- /deploy/streaming-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mastodon-streaming 5 | namespace: default 6 | spec: 7 | type: NodePort 8 | ports: 9 | - name: streaming 10 | port: 4000 11 | targetPort: 4000 12 | protocol: TCP 13 | selector: 14 | app: mastodon-streaming -------------------------------------------------------------------------------- /deploy/web-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: mastodon-web 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: mastodon-web 11 | spec: 12 | containers: 13 | - name: web 14 | image: tootsuite/mastodon:v2.5.0 15 | command: ["/usr/bin/env", "bash", "-c", "bundle exec rails assets:precompile && bundle exec rails s -p 3000 -b 0.0.0.0"] 16 | ports: 17 | - name: web 18 | containerPort: 3000 19 | envFrom: 20 | - configMapRef: 21 | name: mastodon 22 | - secretRef: 23 | name: mastodon 24 | resources: 25 | requests: 26 | memory: 350Mi 27 | cpu: 100m -------------------------------------------------------------------------------- /deploy/web-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mastodon-web 5 | namespace: default 6 | spec: 7 | type: NodePort 8 | ports: 9 | - name: web 10 | port: 3000 11 | targetPort: 3000 12 | protocol: TCP 13 | selector: 14 | app: mastodon-web --------------------------------------------------------------------------------