All checks were successful
Build & Deploy Staging / build-and-deploy (release) Successful in 31s
The v3.3.5 router reads config.LEADERBOARD_INCLUDE_TEST_DEFAULT but the staging compose file was never passing the env through to the container. This change was applied manually on the staging host before but never made it back into the repo — fixing that so CI deploys pick it up. Value on staging is sourced from .env (already set to true). Production leaves it unset, so the default of false applies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
151 lines
4.4 KiB
YAML
151 lines
4.4 KiB
YAML
# Staging Docker Compose for Golf Card Game
|
|
#
|
|
# Mirrors production but with reduced memory limits for 512MB droplet.
|
|
#
|
|
# Usage:
|
|
# docker compose -f docker-compose.staging.yml up -d --build
|
|
|
|
services:
|
|
app:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
environment:
|
|
- POSTGRES_URL=postgresql://golf:${DB_PASSWORD}@postgres:5432/golf
|
|
- DATABASE_URL=postgresql://golf:${DB_PASSWORD}@postgres:5432/golf
|
|
- REDIS_URL=redis://redis:6379
|
|
- SECRET_KEY=${SECRET_KEY}
|
|
- RESEND_API_KEY=${RESEND_API_KEY:-}
|
|
- EMAIL_FROM=${EMAIL_FROM:-Golf Cards <noreply@contact.golfcards.club>}
|
|
- SENTRY_DSN=${SENTRY_DSN:-}
|
|
- ENVIRONMENT=${ENVIRONMENT:-staging}
|
|
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
|
- LOG_LEVEL_GAME=${LOG_LEVEL_GAME:-}
|
|
- LOG_LEVEL_AI=${LOG_LEVEL_AI:-}
|
|
- LOG_LEVEL_HANDLERS=${LOG_LEVEL_HANDLERS:-}
|
|
- LOG_LEVEL_ROOM=${LOG_LEVEL_ROOM:-}
|
|
- LOG_LEVEL_AUTH=${LOG_LEVEL_AUTH:-}
|
|
- LOG_LEVEL_STORES=${LOG_LEVEL_STORES:-}
|
|
- BASE_URL=${BASE_URL:-https://staging.golfcards.club}
|
|
- RATE_LIMIT_ENABLED=false
|
|
- INVITE_ONLY=true
|
|
- INVITE_REQUEST_ENABLED=false
|
|
- DAILY_OPEN_SIGNUPS=${DAILY_OPEN_SIGNUPS:-0}
|
|
- DAILY_SIGNUPS_PER_IP=${DAILY_SIGNUPS_PER_IP:-3}
|
|
- BOOTSTRAP_ADMIN_USERNAME=${BOOTSTRAP_ADMIN_USERNAME:-}
|
|
- BOOTSTRAP_ADMIN_PASSWORD=${BOOTSTRAP_ADMIN_PASSWORD:-}
|
|
- MATCHMAKING_ENABLED=true
|
|
- LEADERBOARD_INCLUDE_TEST_DEFAULT=${LEADERBOARD_INCLUDE_TEST_DEFAULT:-false}
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
deploy:
|
|
replicas: 1
|
|
restart_policy:
|
|
condition: on-failure
|
|
max_attempts: 3
|
|
resources:
|
|
limits:
|
|
memory: 128M
|
|
reservations:
|
|
memory: 48M
|
|
networks:
|
|
- internal
|
|
- web
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=golfgame_web"
|
|
- "traefik.http.routers.golf.rule=Host(`${DOMAIN:-staging.golfcards.club}`)"
|
|
- "traefik.http.routers.golf.entrypoints=websecure"
|
|
- "traefik.http.routers.golf.tls=true"
|
|
- "traefik.http.routers.golf.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.golf.loadbalancer.server.port=8000"
|
|
- "traefik.http.services.golf.loadbalancer.sticky.cookie=true"
|
|
- "traefik.http.services.golf.loadbalancer.sticky.cookie.name=golf_server"
|
|
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
environment:
|
|
POSTGRES_DB: golf
|
|
POSTGRES_USER: golf
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U golf -d golf"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- internal
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 96M
|
|
reservations:
|
|
memory: 48M
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
command: redis-server --appendonly yes --maxmemory 16mb --maxmemory-policy allkeys-lru
|
|
volumes:
|
|
- redis_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- internal
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 32M
|
|
reservations:
|
|
memory: 16M
|
|
|
|
traefik:
|
|
image: traefik:v3.6
|
|
environment:
|
|
- DOCKER_API_VERSION=1.44
|
|
command:
|
|
- "--api.dashboard=true"
|
|
- "--api.insecure=true"
|
|
- "--accesslog=true"
|
|
- "--log.level=WARN"
|
|
- "--providers.docker=true"
|
|
- "--providers.docker.exposedbydefault=false"
|
|
- "--entrypoints.web.address=:80"
|
|
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
|
|
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
|
|
- "--entrypoints.websecure.address=:443"
|
|
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
|
|
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
|
|
- "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}"
|
|
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- letsencrypt:/letsencrypt
|
|
networks:
|
|
- web
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 48M
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
letsencrypt:
|
|
|
|
networks:
|
|
internal:
|
|
driver: bridge
|
|
web:
|
|
driver: bridge
|