# docker-compose.yml version: "3.8" services: db: image: postgres:14-alpine restart: unless-stopped env_file: - .env.production volumes: - db-data:/var/lib/postgresql/data redis: image: redis:6-alpine restart: unless-stopped command: ["redis-server", "--appendonly", "yes"] env_file: - .env.production volumes: - redis-data:/data init: image: ghcr.io/mastodon/mastodon:latest depends_on: - db - redis restart: "no" env_file: - .env.production volumes: - public-system:/mastodon/public/system - public-assets:/mastodon/public/assets - public-packs:/mastodon/public/packs - mastodon-log:/mastodon/log command: > bash -lc " set -euo pipefail echo '== Mastodon init job starting' # 1) Check ActiveRecord encryption keys; if missing, run db:encryption:init to generate and print them then exit. if [ -z \"${ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY:-}\" ] || [ -z \"${ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY:-}\" ] || [ -z \"${ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT:-}\" ]; then echo 'ActiveRecord encryption keys are NOT set. Running bin/rails db:encryption:init to generate keys...' bin/rails db:encryption:init || true echo '=======================================================' echo 'The above command generated ACTIVE_RECORD encryption keys. Copy them into .env.production (use these exact names):' echo ' ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY' echo ' ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY' echo ' ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT' echo '' echo 'After editing .env.production to include the keys, re-run this init job:' echo ' docker-compose run --rm --no-deps init' echo 'Exiting with code 1 so you persist the keys before continuing.' exit 1 fi echo 'ActiveRecord encryption keys present. Continuing initialization...' # 2) Wait for Postgres readiness echo 'Waiting for Postgres to be ready...' attempt=0 until bundle exec rails db:version >/dev/null 2>&1; do attempt=$((attempt+1)) if [ \"$attempt\" -gt 60 ]; then echo 'Timed out waiting for Postgres (60 attempts). Check DB connectivity and env vars.' >&2 exit 2 fi echo \"Postgres not ready yet (attempt $attempt). Sleeping 2s...\" sleep 2 done echo 'Postgres is ready.' # 3) Prepare DB (create/migrate) echo 'Running rails db:prepare (create DB / migrate if needed)...' bundle exec rails db:prepare # 4) Generate VAPID keys if missing (prints keys) if [ -z \"${VAPID_PUBLIC_KEY:-}\" ] || [ -z \"${VAPID_PRIVATE_KEY:-}\" ]; then echo 'VAPID keys (VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY) are missing. Generating...' bundle exec rake mastodon:webpush:generate_vapid_key || true echo '=======================================================' echo 'If VAPID keys were printed above, copy them into .env.production as VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY and re-run init.' else echo 'VAPID keys present.' fi # 5) Install JS deps and precompile assets echo 'Installing javascript dependencies (yarn)...' if command -v yarn >/dev/null 2>&1; then yarn install --check-files --production=false else echo 'yarn not found in image; skipping yarn install (ensure assets are built if image doesn't include yarn).' fi echo 'Precompiling rails assets...' RAILS_ENV=production bundle exec rails assets:precompile echo 'Init job complete. You can now start web/sidekiq/streaming services.' " web: image: ghcr.io/mastodon/mastodon:latest depends_on: - db - redis restart: unless-stopped env_file: - .env.production volumes: - public-system:/mastodon/public/system - public-assets:/mastodon/public/assets - public-packs:/mastodon/public/packs - mastodon-log:/mastodon/log ports: - "3000:3000" command: bash -lc "RAILS_ENV=production bundle exec puma -C config/puma.rb" sidekiq: image: ghcr.io/mastodon/mastodon:latest depends_on: - db - redis restart: unless-stopped env_file: - .env.production volumes: - public-system:/mastodon/public/system - mastodon-log:/mastodon/log command: bash -lc "RAILS_ENV=production bundle exec sidekiq" streaming: image: ghcr.io/mastodon/mastodon:latest depends_on: - redis restart: unless-stopped env_file: - .env.production volumes: - mastodon-log:/mastodon/log ports: - "4000:4000" command: bash -lc "NODE_ENV=production ./bin/streaming" volumes: db-data: redis-data: public-system: public-assets: public-packs: mastodon-log: