name: ballet-island services: postgres: image: postgres:18-alpine restart: unless-stopped environment: POSTGRES_DB: ${PGDATABASE:?Set PGDATABASE in .env} POSTGRES_USER: ${PGUSER:?Set PGUSER in .env} POSTGRES_PASSWORD: ${PGPASSWORD:?Set PGPASSWORD in .env} ports: - "127.0.0.1:${PGPORT:-5432}:5432" volumes: # PostgreSQL 18 stores its versioned data directory under this mount. - postgres_data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""] interval: 5s timeout: 3s retries: 10 start_period: 10s api: build: context: . restart: unless-stopped environment: HTTP_ADDR: :8080 PGHOST: postgres PGPORT: 5432 PGDATABASE: ${PGDATABASE:?Set PGDATABASE in .env} PGUSER: ${PGUSER:?Set PGUSER in .env} PGPASSWORD: ${PGPASSWORD:?Set PGPASSWORD in .env} PGSSLMODE: disable WECHAT_APP_ID: ${WECHAT_APP_ID:-} WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:-} ports: - "${API_BIND:-127.0.0.1}:${API_PORT:-8080}:8080" depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD", "wget", "-q", "-T", "3", "-O", "/dev/null", "http://127.0.0.1:8080/readyz"] interval: 10s timeout: 5s retries: 3 start_period: 10s stop_grace_period: 15s volumes: postgres_data: