# Staging compose overlay (reference only). # # Coolify on the boilerplate-staging host does NOT consume this file directly — # each service is provisioned through the Coolify UI. This overlay is the # human-readable source of truth for how the staging stack is meant to be # wired (PgBouncer in front of Postgres, apps depending on it being healthy) # and can be applied locally for end-to-end smoke tests: # # docker compose -f docker-compose.yml -f docker-compose.staging.yml up \ # postgres pgbouncer api web worker-general worker-mail worker-import worker-webhook worker-plugin # # See docs/ops/pgbouncer.md for the matching Coolify deploy procedure. services: postgres: image: postgres:16-alpine environment: POSTGRES_DB: ${POSTGRES_DB:-boilerplate_validation} POSTGRES_USER: ${POSTGRES_USER:-boilerplate} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-boilerplate} # Required so pg_authid stores SCRAM hashes that pgbouncer can copy # into its userlist.txt. md5 would force a config-time rehash. POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256" command: - postgres - -c - password_encryption=scram-sha-256 # Defensive max_connections so PgBouncer's default_pool_size (25) # multiplied across app stacks stays well below the cap. - -c - max_connections=200 volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-boilerplate} -d ${POSTGRES_DB:-boilerplate_validation}"] interval: 10s timeout: 3s retries: 10 start_period: 20s restart: unless-stopped pgbouncer: depends_on: postgres: condition: service_healthy api: build: context: . target: api environment: # DATABASE_URL flows through pgbouncer; DIRECT_URL stays on postgres. - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} depends_on: pgbouncer: condition: service_healthy redis: condition: service_healthy web: build: context: . target: web environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} depends_on: pgbouncer: condition: service_healthy # Five group-specific worker services share the staging Postgres routing # (DATABASE_URL → pgbouncer, DIRECT_URL → postgres). See # docs/ops/worker-queues.md for the group layout. worker-general: environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} - OUTBOX_DISPATCHER_ENABLED=true - OUTBOX_DISPATCHER_REQUIRED=true - WORKFLOW_TRIGGER_OUTBOX_ENABLED=true - WORKFLOW_TRIGGER_OUTBOX_REQUIRED=true depends_on: pgbouncer: condition: service_healthy worker-mail: environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} depends_on: pgbouncer: condition: service_healthy worker-import: environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} depends_on: pgbouncer: condition: service_healthy worker-webhook: environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} depends_on: pgbouncer: condition: service_healthy worker-plugin: environment: - DATABASE_URL=${DATABASE_URL:-postgres://boilerplate:boilerplate@pgbouncer:6432/boilerplate_validation?pgbouncer=true&connection_limit=10} - DIRECT_URL=${DIRECT_URL:-postgres://boilerplate:boilerplate@postgres:5432/boilerplate_validation} depends_on: pgbouncer: condition: service_healthy volumes: postgres-data: