# Production Docker Compose (default) # # Usage: # cp .env.example .env # then edit .env with real values # docker compose up -d # # For development / E2E testing, use docker-compose.dev.yml instead: # docker compose -f docker-compose.dev.yml up # # All variables marked ${VAR?error} are required — compose will refuse to start # if they are not set in the environment or .env file. services: redis: image: redis:7-alpine restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER?POSTGRES_USER is required} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD?POSTGRES_PASSWORD is required} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 10 api-server: build: context: . dockerfile: bouncr-api-server/Dockerfile restart: unless-stopped networks: default: aliases: - api depends_on: db: condition: service_healthy redis: condition: service_healthy environment: JDBC_URL: jdbc:postgresql://db:5432/${POSTGRES_USER} JDBC_USER: ${POSTGRES_USER} JDBC_PASSWORD: ${POSTGRES_PASSWORD} REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET?JWT_SECRET is required (32+ characters)} INTERNAL_SIGNING_KEY: ${INTERNAL_SIGNING_KEY?INTERNAL_SIGNING_KEY is required} CORS_ORIGINS: ${CORS_ORIGINS?CORS_ORIGINS is required (e.g. https://your-domain.com)} PORT: "3005" ADMIN_PASSWORD: ${ADMIN_PASSWORD?ADMIN_PASSWORD is required} OIDC_KEY_ENCRYPTION_KEY: ${OIDC_KEY_ENCRYPTION_KEY:-} healthcheck: test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:3005/bouncr/api/sign_in; [ $? -ne 4 ]"] interval: 10s timeout: 5s retries: 30 start_period: 30s proxy: build: ./bouncr-proxy restart: unless-stopped depends_on: api-server: condition: service_healthy redis: condition: service_healthy environment: REDIS_URL: redis://redis:6379 DB_DSN: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_USER}?sslmode=disable JWT_SECRET: ${JWT_SECRET} INTERNAL_SIGNING_KEY: ${INTERNAL_SIGNING_KEY} API_SERVER_URL: http://api:3005 LOG_LEVEL: ${LOG_LEVEL:-info} healthcheck: test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:8081/_healthcheck || exit 1"] interval: 10s timeout: 5s retries: 10 envoy: image: envoyproxy/envoy:v1.31-latest restart: unless-stopped command: ["/usr/local/bin/envoy", "-c", "/etc/envoy/envoy.yaml"] depends_on: proxy: condition: service_healthy api-server: condition: service_healthy volumes: - ./envoy/envoy-docker.yaml:/etc/envoy/envoy.yaml:ro ports: - "${LISTEN_PORT:-3000}:3000" ui: build: ./bouncr-ui restart: unless-stopped depends_on: - envoy ports: - "${UI_PORT:-8080}:80" volumes: pgdata: