- docker-compose.prod.yml overlay: Caddy with automatic HTTPS on one origin (web at /, API at /api incl. websocket), internal-only Postgres/ Redis/API/web, secure cookies, private-network servers blocked, nightly pg_dump backups kept 14 days - deploy/export-db.sh and import-db.sh to carry a database to the server (same TOKEN_ENCRYPTION_KEY required for stored connections) - Base compose no longer requires apps/api/.env - README: deployment, Spotify via scrobblers, SMTP settings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
107 lines
2.8 KiB
YAML
107 lines
2.8 KiB
YAML
# Full stack: `docker compose up -d --build`, then open http://localhost:3737
|
|
# Configuration comes from apps/api/.env (copy apps/api/.env.example first).
|
|
|
|
x-api: &api
|
|
build:
|
|
context: .
|
|
dockerfile: apps/api/Dockerfile
|
|
image: musicshare-api:local
|
|
# Local development config; on a server, docker-compose.prod.yml supplies deploy/production.env instead.
|
|
env_file:
|
|
- path: apps/api/.env
|
|
required: false
|
|
environment:
|
|
# Inside the compose network, services reach each other by name.
|
|
DATABASE_URL: postgres://musicshare:musicshare@postgres:5432/musicshare
|
|
REDIS_URL: redis://redis:6379
|
|
extra_hosts:
|
|
# Lets the API reach servers on your machine (e.g. a local Jellyfin) as host.docker.internal
|
|
- host.docker.internal:host-gateway
|
|
init: true
|
|
restart: unless-stopped
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:17
|
|
environment:
|
|
POSTGRES_USER: musicshare
|
|
POSTGRES_PASSWORD: musicshare
|
|
POSTGRES_DB: musicshare
|
|
ports:
|
|
- "${POSTGRES_PORT:-5447}:5432"
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U musicshare -d musicshare"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:7
|
|
# Persist to disk so queued jobs and poll schedules survive restarts.
|
|
command: ["redis-server", "--appendonly", "yes"]
|
|
ports:
|
|
- "${REDIS_PORT:-6380}:6379"
|
|
volumes:
|
|
- redisdata:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
restart: unless-stopped
|
|
|
|
# Applies database migrations, then exits. The API and worker wait for it.
|
|
migrate:
|
|
<<: *api
|
|
command: ["node", "dist/db/migrate.js"]
|
|
restart: "no"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
|
|
api:
|
|
<<: *api
|
|
ports:
|
|
- "${API_PORT:-4000}:4000"
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
worker:
|
|
<<: *api
|
|
command: ["node", "dist/worker.js"]
|
|
healthcheck:
|
|
disable: true
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
web:
|
|
build:
|
|
context: .
|
|
dockerfile: apps/web/Dockerfile
|
|
args:
|
|
# The URL the *browser* uses to reach the API.
|
|
NEXT_PUBLIC_API_URL: ${PUBLIC_API_URL:-http://localhost:4000}
|
|
# Optional donation link shown on the website, e.g. DONATION_URL=https://ko-fi.com/you
|
|
NEXT_PUBLIC_DONATION_URL: ${DONATION_URL:-}
|
|
image: musicshare-web:local
|
|
ports:
|
|
- "${WEB_PORT:-3737}:3737"
|
|
init: true
|
|
restart: unless-stopped
|
|
depends_on:
|
|
api:
|
|
condition: service_healthy
|
|
|
|
volumes:
|
|
pgdata:
|
|
redisdata:
|