services: db: image: postgres:17-alpine environment: POSTGRES_DB: rf4_spotter POSTGRES_USER: rf4 POSTGRES_PASSWORD: rf4_local healthcheck: test: ["CMD-SHELL", "pg_isready -U rf4 -d rf4_spotter"] interval: 5s timeout: 3s retries: 10 volumes: - postgres_data:/var/lib/postgresql/data minio: image: minio/minio:RELEASE.2025-07-23T15-54-02Z command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${S3_ACCESS_KEY:-rf4-local} MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:-rf4-local-secret} ports: - "9000:9000" - "9001:9001" healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:9000/minio/health/live"] interval: 5s timeout: 3s retries: 10 volumes: - minio_data:/data api: build: context: . dockerfile: apps/api/Dockerfile environment: DATABASE_URL: postgresql+psycopg://rf4:rf4_local@db:5432/rf4_spotter ADMIN_TOKEN: ${ADMIN_TOKEN:-change-me-in-production} S3_ENDPOINT_URL: http://minio:9000 S3_PUBLIC_ENDPOINT_URL: ${S3_PUBLIC_ENDPOINT_URL:-http://localhost:9000} S3_ACCESS_KEY: ${S3_ACCESS_KEY:-rf4-local} S3_SECRET_KEY: ${S3_SECRET_KEY:-rf4-local-secret} S3_BUCKET: ${S3_BUCKET:-catch-screenshots} OFFICIAL_RECORDS_URL: ${OFFICIAL_RECORDS_URL:-https://rf4game.de/records/region/RU/} OFFICIAL_RECORDS_REGION: ${OFFICIAL_RECORDS_REGION:-RU} OFFICIAL_RECORDS_CATEGORY: ${OFFICIAL_RECORDS_CATEGORY:-records} OFFICIAL_IMPORT_REQUIRED: ${OFFICIAL_IMPORT_REQUIRED:-false} RATE_LIMIT_SECRET: ${RATE_LIMIT_SECRET:-change-rate-limit-secret} depends_on: db: condition: service_healthy minio: condition: service_healthy ports: - "8000:8000" healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/ready')"] interval: 5s timeout: 3s retries: 12 web: build: ./apps/web environment: PUBLIC_API_URL: http://localhost:8000 API_INTERNAL_URL: http://api:8000 depends_on: api: condition: service_healthy ports: - "4321:4321" healthcheck: test: ["CMD", "node", "-e", "fetch('http://localhost:4321').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] interval: 5s timeout: 3s retries: 10 importer: build: context: . dockerfile: apps/api/Dockerfile profiles: ["tools"] environment: DATABASE_URL: postgresql+psycopg://rf4:rf4_local@db:5432/rf4_spotter depends_on: db: condition: service_healthy command: ["sh", "-c", "alembic upgrade head && python -m app.cli import-records"] scheduler: build: context: . dockerfile: apps/api/Dockerfile profiles: ["scheduler"] restart: unless-stopped environment: DATABASE_URL: postgresql+psycopg://rf4:rf4_local@db:5432/rf4_spotter OFFICIAL_RECORDS_URL: ${OFFICIAL_RECORDS_URL:-https://rf4game.de/records/region/RU/} OFFICIAL_RECORDS_REGION: ${OFFICIAL_RECORDS_REGION:-RU} OFFICIAL_RECORDS_CATEGORY: ${OFFICIAL_RECORDS_CATEGORY:-records} IMPORT_INTERVAL_SECONDS: ${IMPORT_INTERVAL_SECONDS:-3600} depends_on: api: condition: service_healthy command: ["python", "-m", "app.scheduler"] volumes: postgres_data: minio_data: