services: postgres: image: postgres:16-alpine command: - postgres - -p - ${POSTGRES_PORT:-5432} environment: POSTGRES_DB: ${POSTGRES_DB:-hll_vietnam} POSTGRES_USER: ${POSTGRES_USER:-hll_vietnam} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} POSTGRES_PORT: ${POSTGRES_PORT:-5432} TZ: Europe/Madrid ports: - "${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432}" volumes: - jta-postgres-data:/var/lib/postgresql/data - ./backups:/backups healthcheck: test: - CMD-SHELL - pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -p "$$POSTGRES_PORT" interval: 10s timeout: 5s retries: 12 restart: unless-stopped backend: image: hll-vietnam-backend:jta build: context: ../../backend dockerfile: Dockerfile environment: &backend_environment HLL_BACKEND_HOST: 0.0.0.0 HLL_BACKEND_PORT: ${BACKEND_PORT:-8000} HLL_BACKEND_DATABASE_URL: ${HLL_BACKEND_DATABASE_URL:?HLL_BACKEND_DATABASE_URL is required} HLL_BACKEND_ALLOWED_ORIGINS: ${HLL_BACKEND_ALLOWED_ORIGINS:?HLL_BACKEND_ALLOWED_ORIGINS is required} HLL_BACKEND_LIVE_DATA_SOURCE: ${HLL_BACKEND_LIVE_DATA_SOURCE:-rcon} HLL_BACKEND_HISTORICAL_DATA_SOURCE: ${HLL_BACKEND_HISTORICAL_DATA_SOURCE:-rcon} HLL_BACKEND_RCON_TARGETS: ${HLL_BACKEND_RCON_TARGETS:?HLL_BACKEND_RCON_TARGETS is required} HLL_DB_MAINTENANCE_ENABLED: ${HLL_DB_MAINTENANCE_ENABLED:-false} HLL_DB_MAINTENANCE_INTERVAL_SECONDS: ${HLL_DB_MAINTENANCE_INTERVAL_SECONDS:-43200} HLL_RECENT_MATCHES_KEEP: ${HLL_RECENT_MATCHES_KEEP:-100} HLL_ADMIN_LOG_NONCRITICAL_RETENTION_DAYS: ${HLL_ADMIN_LOG_NONCRITICAL_RETENTION_DAYS:-30} HLL_ADMIN_LOG_CRITICAL_RETENTION_DAYS: ${HLL_ADMIN_LOG_CRITICAL_RETENTION_DAYS:-90} HLL_SERVER_SNAPSHOT_RETENTION_DAYS: ${HLL_SERVER_SNAPSHOT_RETENTION_DAYS:-14} HLL_DB_MAINTENANCE_BATCH_SIZE: ${HLL_DB_MAINTENANCE_BATCH_SIZE:-5000} ports: - "${BACKEND_PORT:-8000}:${BACKEND_PORT:-8000}" depends_on: postgres: condition: service_healthy volumes: - jta-backend-data:/app/data restart: unless-stopped frontend: build: context: ../../frontend dockerfile: Dockerfile command: - sh - -c - | python - <<'PY' import os import re from pathlib import Path base_url = os.environ.get("FRONTEND_BACKEND_BASE_URL", "http://127.0.0.1:8000") pattern = re.compile(r'data-backend-base-url="[^"]*"') replacement = f'data-backend-base-url="{base_url}"' for path in Path("/srv/frontend").glob("*.html"): text = path.read_text(encoding="utf-8") text = pattern.sub(replacement, text) path.write_text(text, encoding="utf-8") PY python -m http.server "${FRONTEND_PORT:-8080}" --bind 0.0.0.0 --directory /srv/frontend environment: FRONTEND_PORT: ${FRONTEND_PORT:-8080} FRONTEND_BACKEND_BASE_URL: ${FRONTEND_BACKEND_BASE_URL:?FRONTEND_BACKEND_BASE_URL is required} ports: - "${FRONTEND_PORT:-8080}:${FRONTEND_PORT:-8080}" depends_on: backend: condition: service_started restart: unless-stopped historical-runner: profiles: - advanced image: hll-vietnam-backend:jta build: context: ../../backend dockerfile: Dockerfile command: - python - -m - app.historical_runner - --hourly environment: <<: *backend_environment depends_on: postgres: condition: service_healthy backend: condition: service_started volumes: - jta-backend-data:/app/data restart: unless-stopped rcon-historical-worker: profiles: - advanced image: hll-vietnam-backend:jta build: context: ../../backend dockerfile: Dockerfile command: - python - -m - app.rcon_historical_worker - loop environment: <<: *backend_environment HLL_RCON_HISTORICAL_CAPTURE_INTERVAL_SECONDS: ${HLL_BACKEND_RCON_HISTORICAL_INTERVAL_SECONDS:-600} HLL_BACKEND_RCON_ADMIN_LOG_LOOKBACK_MINUTES: ${HLL_BACKEND_RCON_ADMIN_LOG_LOOKBACK_MINUTES:-10} depends_on: postgres: condition: service_healthy backend: condition: service_started volumes: - jta-backend-data:/app/data restart: unless-stopped volumes: jta-postgres-data: jta-backend-data: