name: ${COMPOSE_PROJECT_NAME:-sammo-public} services: postgres: image: postgres:18.4-bookworm environment: POSTGRES_DB: ${POSTGRES_DB:-sammo} POSTGRES_USER: ${POSTGRES_USER:-sammo} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env} TZ: ${TZ:-Asia/Seoul} volumes: - postgres-data:/var/lib/postgresql healthcheck: test: [CMD-SHELL, 'pg_isready -U "$${POSTGRES_USER}" -d "$${POSTGRES_DB}"'] interval: 5s timeout: 5s retries: 24 start_period: 10s restart: unless-stopped redis: image: redis:8.2.7-bookworm entrypoint: [/usr/local/bin/sammo-redis-entrypoint] environment: REDIS_PASSWORD: ${REDIS_PASSWORD:?set REDIS_PASSWORD in .env} volumes: - redis-data:/data - ./runtime/redis-entrypoint.sh:/usr/local/bin/sammo-redis-entrypoint:ro healthcheck: test: [CMD-SHELL, 'REDISCLI_AUTH="$${REDIS_PASSWORD}" redis-cli ping 2>/dev/null | grep -q PONG'] interval: 5s timeout: 5s retries: 24 start_period: 5s restart: unless-stopped runtime: build: context: . dockerfile: runtime/Dockerfile environment: CORE_SOURCE_MODE: clone CORE_REPOSITORY_URL: ${CORE_REPOSITORY_URL:?set CORE_REPOSITORY_URL in .env} CORE_BOOTSTRAP_REF: ${CORE_BOOTSTRAP_REF:-main} POSTGRES_HOST: postgres POSTGRES_PORT: '5432' POSTGRES_DB: ${POSTGRES_DB:-sammo} POSTGRES_USER: ${POSTGRES_USER:-sammo} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env} GATEWAY_DB_SCHEMA: public REDIS_HOST: redis REDIS_PORT: '6379' REDIS_DB: '0' REDIS_PASSWORD: ${REDIS_PASSWORD:?set REDIS_PASSWORD in .env} GAME_TOKEN_SECRET: ${GAME_TOKEN_SECRET:?set GAME_TOKEN_SECRET in .env} GATEWAY_BOOTSTRAP_TOKEN: ${GATEWAY_BOOTSTRAP_TOKEN:?set GATEWAY_BOOTSTRAP_TOKEN in .env} INITIAL_ADMIN_USERNAME: ${INITIAL_ADMIN_USERNAME:?set INITIAL_ADMIN_USERNAME in .env} INITIAL_ADMIN_PASSWORD: ${INITIAL_ADMIN_PASSWORD:?set INITIAL_ADMIN_PASSWORD in .env} INITIAL_ADMIN_DISPLAY_NAME: ${INITIAL_ADMIN_DISPLAY_NAME:-Administrator} BOOTSTRAP_PROFILES: ${BOOTSTRAP_PROFILES:-gateway,che,kwe,pwe,twe,nya,pya,hwe} KAKAO_REST_KEY: ${KAKAO_REST_KEY:?set KAKAO_REST_KEY in .env} KAKAO_ADMIN_KEY: ${KAKAO_ADMIN_KEY:-} KAKAO_REDIRECT_URI: ${PUBLIC_SCHEME:-https}://${DOMAIN:?set DOMAIN in .env}/gateway/oauth/callback GATEWAY_PUBLIC_URL: ${PUBLIC_SCHEME:-https}://${DOMAIN:?set DOMAIN in .env}/gateway/ GATEWAY_USER_ICON_DIR: /srv/data/user-icons GATEWAY_USER_ICON_PUBLIC_URL: ${PUBLIC_SCHEME:-https}://${DOMAIN:?set DOMAIN in .env}/gateway/api/user-icons GATEWAY_LOCAL_REGISTRATION_ENABLED: ${GATEWAY_LOCAL_REGISTRATION_ENABLED:-true} GATEWAY_ADMIN_LOCAL_ACCOUNT_ENABLED: ${GATEWAY_ADMIN_LOCAL_ACCOUNT_ENABLED:-true} GATEWAY_LOCAL_ACCOUNT_GRACE_DAYS: ${GATEWAY_LOCAL_ACCOUNT_GRACE_DAYS:-7} GATEWAY_LEGACY_PASSWORD_GLOBAL_SALT: ${GATEWAY_LEGACY_PASSWORD_GLOBAL_SALT:-} GATEWAY_API_HOST: 0.0.0.0 GATEWAY_API_PORT: '15001' GATEWAY_FRONTEND_PORT: '15000' GATEWAY_TRPC_PATH: /gateway/api/trpc GATEWAY_INTERNAL_API_URL: http://127.0.0.1:15001 GATEWAY_REDIS_PREFIX: sammo:gateway GATEWAY_WORKSPACE_ROOT: /srv/core/repository GATEWAY_WORKTREE_ROOT: /srv/core/profile-worktrees RELEASE_CONTROLLER_WORKSPACE_ROOT: /srv/core/repository RELEASE_CONTROLLER_WORKTREE_ROOT: /srv/core/release-worktrees GATEWAY_BASE_PATH: /gateway VITE_APP_BASE_PATH: /gateway VITE_GATEWAY_API_URL: /gateway/api/trpc VITE_GAME_API_URL_TEMPLATE: /{profile}/api/trpc VITE_GAME_WEB_URL_TEMPLATE: /{profile}/ VITE_GATEWAY_USER_ICON_BASE_URL: /gateway/api/user-icons VITE_PREVIEW_ALLOWED_HOSTS: ${DOMAIN:?set DOMAIN in .env} PM2_HOME: /srv/data/pm2 TZ: ${TZ:-Asia/Seoul} volumes: - core-source:/srv/core - runtime-data:/srv/data depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: [CMD, curl, --fail, --silent, http://127.0.0.1:15001/healthz] interval: 10s timeout: 5s retries: 30 start_period: 5m restart: unless-stopped caddy: image: caddy:2.10.2-alpine environment: DOMAIN: ${DOMAIN:?set DOMAIN in .env} SITE_ADDRESS: ${DOMAIN:?set DOMAIN in .env} ACME_EMAIL: ${ACME_EMAIL:?set ACME_EMAIL in .env} ports: - ${HTTP_PORT:-80}:80 - ${HTTPS_PORT:-443}:443 - ${HTTPS_PORT:-443}:443/udp volumes: - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro - ./data/image:/srv/image:ro - caddy-data:/data - caddy-config:/config depends_on: runtime: condition: service_healthy restart: unless-stopped volumes: postgres-data: redis-data: core-source: runtime-data: caddy-data: caddy-config: