version: '3.9' services: # ============================================ # Infrastructure Services # ============================================ postgres: image: postgres:16-alpine container_name: manacore-postgres-staging restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-manacore} POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] interval: 10s timeout: 5s retries: 5 networks: - manacore-network redis: image: redis:7-alpine container_name: manacore-redis-staging restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD:-redis123} volumes: - redis_data:/data ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 5s retries: 5 networks: - manacore-network # ============================================ # Backend Services # ============================================ mana-core-auth: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/mana-core-auth:${AUTH_VERSION:-latest} container_name: mana-core-auth-staging restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: NODE_ENV: staging PORT: 3001 DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/manacore_auth REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} JWT_SECRET: ${JWT_SECRET} JWT_PUBLIC_KEY: ${JWT_PUBLIC_KEY} JWT_PRIVATE_KEY: ${JWT_PRIVATE_KEY} ports: - "3001:3001" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/api/v1/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" maerchenzauber-backend: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/maerchenzauber-backend:${MAERCHENZAUBER_VERSION:-latest} container_name: maerchenzauber-backend-staging restart: unless-stopped depends_on: mana-core-auth: condition: service_healthy environment: NODE_ENV: staging PORT: 3002 MANA_SERVICE_URL: http://mana-core-auth:3001 SUPABASE_URL: ${SUPABASE_URL} SUPABASE_ANON_KEY: ${SUPABASE_ANON_KEY} SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} AZURE_OPENAI_ENDPOINT: ${AZURE_OPENAI_ENDPOINT} AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY} AZURE_OPENAI_API_VERSION: ${AZURE_OPENAI_API_VERSION:-2024-12-01-preview} ports: - "3002:3002" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3002/health"] interval: 30s timeout: 10s retries: 3 networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" chat-backend: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/chat-backend:${CHAT_VERSION:-latest} container_name: chat-backend-staging restart: unless-stopped depends_on: mana-core-auth: condition: service_healthy environment: NODE_ENV: staging PORT: 3002 MANA_SERVICE_URL: http://mana-core-auth:3001 SUPABASE_URL: ${SUPABASE_URL} SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} AZURE_OPENAI_ENDPOINT: ${AZURE_OPENAI_ENDPOINT} AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY} AZURE_OPENAI_API_VERSION: ${AZURE_OPENAI_API_VERSION:-2024-12-01-preview} ports: - "3003:3002" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3002/api/health"] interval: 30s timeout: 10s retries: 3 networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" manadeck-backend: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/manadeck-backend:${MANADECK_VERSION:-latest} container_name: manadeck-backend-staging restart: unless-stopped depends_on: mana-core-auth: condition: service_healthy environment: NODE_ENV: staging PORT: 3003 MANA_SERVICE_URL: http://mana-core-auth:3001 SUPABASE_URL: ${SUPABASE_URL} SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} ports: - "3004:3003" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3003/health"] interval: 30s timeout: 10s retries: 3 networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" nutriphi-backend: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/nutriphi-backend:${NUTRIPHI_VERSION:-latest} container_name: nutriphi-backend-staging restart: unless-stopped depends_on: mana-core-auth: condition: service_healthy environment: NODE_ENV: staging PORT: 3004 MANA_SERVICE_URL: http://mana-core-auth:3001 SUPABASE_URL: ${SUPABASE_URL} SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} ports: - "3005:3004" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3004/health"] interval: 30s timeout: 10s retries: 3 networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" news-api: image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/news-api:${NEWS_VERSION:-latest} container_name: news-api-staging restart: unless-stopped depends_on: mana-core-auth: condition: service_healthy environment: NODE_ENV: staging PORT: 3005 MANA_SERVICE_URL: http://mana-core-auth:3001 ports: - "3006:3005" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3005/health"] interval: 30s timeout: 10s retries: 3 networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ============================================ # Reverse Proxy (Optional) # ============================================ nginx: image: nginx:alpine container_name: manacore-nginx-staging restart: unless-stopped depends_on: - mana-core-auth - maerchenzauber-backend - chat-backend volumes: - ./docker/nginx/staging.conf:/etc/nginx/conf.d/default.conf - ./docker/nginx/ssl:/etc/nginx/ssl ports: - "80:80" - "443:443" networks: - manacore-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ============================================ # Networks # ============================================ networks: manacore-network: driver: bridge name: manacore-staging # ============================================ # Volumes # ============================================ volumes: postgres_data: name: manacore-postgres-staging redis_data: name: manacore-redis-staging