services: backend: image: jhalitaksoy/mancala-backend:latest build: context: .. dockerfile: apps/backend/Dockerfile environment: # Must match the iss claim, i.e. the public Keycloak URL; https://auth.playmancala.app/realms/mancala in production KEYCLOAK_ISSUER: ${KEYCLOAK_HOSTNAME:-http://localhost:8080}/realms/mancala # Fetch keys over the compose network instead of the public URL KEYCLOAK_JWKS_URL: http://keycloak:8080/realms/mancala/protocol/openid-connect/certs KEYCLOAK_CLIENT_IDS: mancala-web LEGACY_USERKEY_AUTH: ${LEGACY_USERKEY_AUTH:-true} DATABASE_JDBC_URL: jdbc:postgresql://postgres:5432/mancala DATABASE_USERNAME: mancala DATABASE_PASSWORD: ${MANCALA_DB_PASSWORD} VALKEY_URL: redis://valkey:6379 ports: - "5000:6000" depends_on: - postgres - valkey frontend: image: jhalitaksoy/mancala-frontend:latest build: context: .. dockerfile: apps/frontend/Dockerfile args: KEYCLOAK_URL: ${KEYCLOAK_HOSTNAME:-http://localhost:8080} ports: - "3000:3000" # Shared by Keycloak and the game, each with its own database and user (see postgres/init). postgres: image: postgres:17.6 environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in apps/.env} KEYCLOAK_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD:?set KEYCLOAK_DB_PASSWORD in apps/.env} MANCALA_DB_PASSWORD: ${MANCALA_DB_PASSWORD:?set MANCALA_DB_PASSWORD in apps/.env} volumes: - postgres-data:/var/lib/postgresql/data - ./postgres/init:/docker-entrypoint-initdb.d:ro ports: - "127.0.0.1:5433:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10 # Live game state and caches; the append-only file keeps live games across restarts. valkey: image: valkey/valkey:9.1.2 command: ["valkey-server", "--appendonly", "yes"] volumes: - valkey-data:/data ports: - "127.0.0.1:6379:6379" healthcheck: test: ["CMD", "valkey-cli", "ping"] interval: 5s timeout: 5s retries: 10 keycloak: image: jhalitaksoy/mancala-keycloak:latest build: ./keycloak environment: KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD} # Public URL of Keycloak; https://auth.playmancala.app in production KC_HOSTNAME: ${KEYCLOAK_HOSTNAME:-http://localhost:8080} KC_HTTP_ENABLED: "true" KC_PROXY_HEADERS: xforwarded # Only used to create the master admin on the very first start KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN_USERNAME:-admin} KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:?set KEYCLOAK_ADMIN_PASSWORD in apps/.env} ports: - "127.0.0.1:8080:8080" depends_on: postgres: condition: service_healthy volumes: postgres-data: valkey-data: