services:
  redis:
    image: redis:7.4.2-alpine@sha256:02419de7eddf55aa5bcf49efb74e88fa8d931b4d77c07eff8a6b2144472b6952
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - staging-redis-data:/data
    networks: [staging]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 20s
      timeout: 5s
      retries: 3
      start_period: 10s

  backend:
    image: ${STAGING_SERVER_IMAGE:?STAGING_SERVER_IMAGE is required}
    restart: unless-stopped
    env_file: ${STAGING_RUNTIME_ENV:-/etc/helix/staging/runtime.env}
    environment:
      APP_ENV: staging
      CORS_ORIGINS: '["https://staging.helix.pingcap.net"]'
    depends_on:
      redis:
        condition: service_healthy
    networks: [staging]
    ports:
      - "127.0.0.1:8000:8000"
    healthcheck:
      test:
        - CMD
        - /app/.venv/bin/python
        - -c
        - "import sys, urllib.request; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/api/v1/ready', timeout=5).status == 200 else 1)"
      interval: 20s
      timeout: 10s
      retries: 3
      start_period: 20s

  frontend:
    image: ${STAGING_WEB_IMAGE:?STAGING_WEB_IMAGE is required}
    restart: unless-stopped
    networks: [staging]
    ports:
      - "127.0.0.1:8080:80"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/"]
      interval: 20s
      timeout: 10s
      retries: 3
      start_period: 10s

networks:
  # Caddy is independently attached to this existing, host-owned network.
  # It is deliberately external so a bad deploy cannot silently create an edge
  # network that Caddy does not use.
  staging:
    name: ${STAGING_DOCKER_NETWORK:?STAGING_DOCKER_NETWORK is required}
    external: true

volumes:
  # Staging Redis is retained across backend/frontend image replacements.  The
  # host pre-creates/adopts this exact volume during one-time bootstrap.
  staging-redis-data:
    name: ${STAGING_REDIS_VOLUME:?STAGING_REDIS_VOLUME is required}
    external: true
