Skip to content

Instantly share code, notes, and snippets.

@emilyst
Last active November 19, 2022 19:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emilyst/da4d844da46672f7c9b9509e146cb028 to your computer and use it in GitHub Desktop.
Save emilyst/da4d844da46672f7c9b9509e146cb028 to your computer and use it in GitHub Desktop.
Current docker-compose.yml for my Mastodon instance, and associated files. CUSTOMIZE FOR YOUR PURPOSES. PROVIDED AS-IS. This is just a (probably dated) version of what I happen to use, and it's jank as hell.
version: "3"
services:
db:
image: postgres:15
container_name: mastodon-postgres
restart: unless-stopped
networks:
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
shm_size: 256mb
mem_limit: 2048M
mem_reservation: 512M
healthcheck:
test: pg_isready -U mastodon -d mastodon_production
interval: 5s
timeout: 10s
retries: 30
volumes:
- ./var-lib-postgresql-data:/var/lib/postgresql/data
- /etc/passwd:/etc/passwd:ro
env_file:
- .env
redis:
image: redis:6
container_name: mastodon-redis
restart: unless-stopped
networks:
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: redis-server --save 60 1
healthcheck:
test: redis-cli ping
interval: 5s
timeout: 10s
retries: 30
volumes:
- ./data:/data
env_file:
- .env
elasticsearch:
image: elasticsearch:8.5.0
container_name: mastodon-elasticsearch
restart: "no"
networks:
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 2048M
mem_reservation: 512M
ulimits:
memlock:
soft: -1
hard: -1
healthcheck:
test: curl http://elasticsearch:9200/_cluster/health?wait_for_status=yellow&timeout=1s
interval: 5s
timeout: 10s
retries: 30
volumes:
- ./usr-share-elasticsearch-data:/usr/share/elasticsearch/data
env_file:
- .env
web:
image: tootsuite/mastodon:latest
container_name: mastodon-web
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 2048M
mem_reservation: 512M
command:
- /bin/sh
- -c
- |
rm -f /mastodon/tmp/pids/server.pid
sed -i -e "s/MAX_CHARS = [0-9]*/MAX_CHARS = 65536/" app/validators/status_length_validator.rb
sed -i -e "s/length(fulltext) > [0-9]*/length(fulltext) > 65536/" app/javascript/mastodon/features/compose/components/compose_form.js
sed -i -e "s/length(text) > [0-9]*/length(text) > 65536/" app/javascript/mastodon/features/compose/components/compose_form.js
sed -i -e "s/CharacterCounter max={[0-9]*}/CharacterCounter max={65536}/" app/javascript/mastodon/features/compose/components/compose_form.js
sed -i -e "s/:languages, :registrations,/:languages, :registrations, :max_toot_chars,/" app/serializers/rest/instance_serializer.rb
sed -i -e "/private$$/i \ \ def max_toot_chars; 65535; end\n" app/serializers/rest/instance_serializer.rb
sed -i -e "s/IMAGE_LIMIT = [0-9]*/IMAGE_LIMIT = 25/" app/models/media_attachment.rb
bundle exec rails db:migrate
bundle exec rails assets:precompile
bundle exec rails server -p 3000
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
ports:
- "30000:3000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes:
- ./mastodon-public-system:/mastodon/public/system
env_file:
- .env
api:
image: tootsuite/mastodon:latest
container_name: mastodon-api
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 2048M
mem_reservation: 512M
command: node ./streaming
ports:
- "40000:4000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
env_file:
- .env
sidekiq-default:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-default
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 25 -q default
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 25
sidekiq-push:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-push
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 25 -q push
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 25
sidekiq-ingress:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-ingress
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 25 -q ingress
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 25
sidekiq-mailers:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-mailers
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 2 -q mailers
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 2
sidekiq-pull:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-pull
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 25 -q pull
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 25
sidekiq-scheduler:
image: tootsuite/mastodon:latest
container_name: mastodon-sidekiq-scheduler
restart: unless-stopped
networks:
- external
- internal
sysctls:
net.ipv6.conf.all.disable_ipv6: 1
mem_limit: 512M
mem_reservation: 128M
command: bundle exec sidekiq -c 5 -q scheduler
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes_from:
- web
env_file:
- .env
environment:
DB_POOL: 5
networks:
external:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.2.20.0/24
internal:
internal: true
ipam:
config:
- subnet: 10.2.21.0/24
ALLOWED_PRIVATE_ADDRESSES=10.0.0.0/8,172.17.0.0/24,10.2.20.0/24,10.2.21.0/24
AUTHORIZED_FETCH=false
BIND=0.0.0.0
DB_HOST=db
DB_NAME=mastodon_production
DB_PASS=[redacted]
DB_PORT=5432
DB_USER=mastodon
ES_ENABLED=true
ES_HOST=elasticsearch
ES_PORT=9200
LOCAL_DOMAIN=emily.news
NODE_ENV=production
MAX_THREADS=5
WEB_CONCURRENCY=3
OTP_SECRET=[redacted]
PGDATA=/var/lib/postgresql/data
POSTGRES_DB=mastodon_production
POSTGRES_PASSWORD=[redacted]
POSTGRES_USER=mastodon
RAILS_ENV=production
RAILS_LOG_LEVEL=info
RAILS_SERVE_STATIC_FILES=false
REDIS_HOST=redis
REDIS_PORT=6379
SECRET_KEY_BASE=[redacted]
SINGLE_USER_MODE=false
SMTP_AUTH_METHOD=login
SMTP_DELIVERY_METHOD=smtp
SMTP_FROM_ADDRESS=Mastodon Notifications <mastodon-notifications@emily.st>
SMTP_LOGIN=[redacted]
SMTP_PASSWORD=[redacted]
SMTP_PORT=465
SMTP_SERVER=[redacted]
SMTP_SSL=true
STREAMING_API_BASE_URL=wss://social-api.emily.news
TRUSTED_PROXY_IP=172.17.0.1
VAPID_PRIVATE_KEY=[redacted]
VAPID_PUBLIC_KEY=[redacted]
WEB_DOMAIN=social.emily.news
ES_JAVA_OPTS=-Xms512m -Xmx512m
ingest.geoip.downloader.enabled=false
xpack.license.self_generated.type=basic
xpack.security.enabled=false
xpack.watcher.enabled=false
xpack.graph.enabled=false
xpack.ml.enabled=false
node.store.allow_mmap=false
bootstrap.memory_lock=true
cluster.name=es-mastodon
discovery.type=single-node
thread_pool.write.queue_size=1000
# this nginx.conf file is mostly irrelevant but demonstrates how to redirect
# to .well-known from the nginx serving up the main domain
pid /var/run/nginx.pid;
worker_processes auto;
events {
include /etc/nginx.custom.events.d/*.conf;
worker_connections 4096;
}
http {
include /etc/nginx/mime.types;
log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$http_x_forwarded_proto://$host" "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 20;
client_header_timeout 20;
client_body_timeout 20;
reset_timedout_connection on;
send_timeout 20;
types_hash_max_size 2048;
server_names_hash_bucket_size 128;
charset UTF-8;
open_file_cache max=100000 inactive=600s;
open_file_cache_valid 600s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
server_tokens off;
access_log /var/log/nginx/access.log main buffer=64k flush=5m;
error_log /var/log/nginx/error.log;
server {
listen 8080;
server_name emily.news;
root /var/www/html;
index index.php;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# https://docs.joinmastodon.org/admin/config/#basic
location /.well-known/webfinger {
return 301 https://social.emily.news$request_uri;
}
# https://github.com/jhass/nodeinfo
location /.well-known/nodeinfo {
return 301 https://social.emily.news$request_uri;
}
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ghost:2368;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment