# Manage production stack — backend + frontend only.
#
# Manage does NOT deploy its own Grafana/Prometheus/Loki/Alertmanager stack.
# It exposes a /metrics endpoint and optional Alertmanager proxy endpoints so
# an *existing* observability deployment can scrape/consume them.
#
# For a ready-to-use example observability stack, see
# docker-compose.observability.yml and docs/observability-runbooks.md.

services:
  backend:
    build:
      context: .
      dockerfile: backend/Dockerfile
      args:
        APP_VERSION: ${APP_VERSION:-0.1.0}
        APP_BUILD_INFO: ${APP_BUILD_INFO:-dev}
    environment:
      AUTH_ENABLED: ${AUTH_ENABLED:-true}
      OIDC_ISSUER_URL: ${OIDC_ISSUER_URL:?set OIDC_ISSUER_URL}
      OIDC_AUDIENCE: ${OIDC_AUDIENCE:?set OIDC_AUDIENCE}
      OIDC_JWKS_URL: ${OIDC_JWKS_URL:-}
      OIDC_CLOCK_SKEW_SECONDS: ${OIDC_CLOCK_SKEW_SECONDS:-30}
      LOG_LEVEL: ${LOG_LEVEL:-INFO}
      LOG_FORMAT: ${LOG_FORMAT:-text}
      PROMETHEUS_ENABLED: "true"
      SMTP_HOST: ${SMTP_HOST:-}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_USERNAME: ${SMTP_USERNAME:-}
      SMTP_PASSWORD: ${SMTP_PASSWORD:-}
      SMTP_FROM_ADDRESS: ${SMTP_FROM_ADDRESS:-}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Manage}
      SMTP_USE_TLS: ${SMTP_USE_TLS:-true}
      SMTP_USE_SSL: ${SMTP_USE_SSL:-false}
      SMTP_TIMEOUT: ${SMTP_TIMEOUT:-30}
      SSH_KNOWN_HOSTS_PATH: /app/backend/.cache/known_hosts
      MANAGE_ENCRYPTION_KEY: ${MANAGE_ENCRYPTION_KEY:?generate one with python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"}
    volumes:
      - ${BACKEND_CACHE_DIR:-./backend-cache}:/app/backend/.cache
    restart: unless-stopped
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${BACKEND_APP_NAME:-manage-backend}.rule=Host(`${BACKEND_APP_HOST:?set BACKEND_APP_HOST}`)"
      - "traefik.http.routers.${BACKEND_APP_NAME:-manage-backend}.entrypoints=websecure"
      - "traefik.http.routers.${BACKEND_APP_NAME:-manage-backend}.tls.certresolver=${CERT_RESOLVER:?set CERT_RESOLVER}"
      - "traefik.http.services.${BACKEND_APP_NAME:-manage-backend}.loadbalancer.server.port=${BACKEND_APP_PORT:-8000}"
    healthcheck:
      test:
        [
          "CMD",
          "python",
          "-c",
          "import json, urllib.request; print(json.load(urllib.request.urlopen('http://127.0.0.1:8000/api/health'))['status'])",
        ]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

  frontend:
    build:
      context: .
      dockerfile: frontend/Dockerfile
      target: prod
      args:
        VITE_API_URL: ${VITE_API_URL:-/api}
        VITE_OIDC_ENABLED: ${VITE_OIDC_ENABLED:-true}
        VITE_OIDC_ISSUER: ${VITE_OIDC_ISSUER:?set VITE_OIDC_ISSUER}
        VITE_OIDC_CLIENT_ID: ${VITE_OIDC_CLIENT_ID:?set VITE_OIDC_CLIENT_ID}
        VITE_OIDC_SCOPE: ${VITE_OIDC_SCOPE:-openid profile email}
        VITE_OIDC_REDIRECT_URI: ${VITE_OIDC_REDIRECT_URI:?set VITE_OIDC_REDIRECT_URI}
        VITE_OIDC_POST_LOGOUT_REDIRECT_URI: ${VITE_OIDC_POST_LOGOUT_REDIRECT_URI:?set VITE_OIDC_POST_LOGOUT_REDIRECT_URI}
        VITE_DEV_API_PROXY_TARGET: ${VITE_DEV_API_PROXY_TARGET:-http://backend:8000}
        VITE_APP_VERSION: ${APP_VERSION:-0.1.0}
        VITE_APP_BUILD_INFO: ${APP_BUILD_INFO:-dev}
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${FRONTEND_APP_NAME:-manage-frontend}.rule=Host(`${FRONTEND_APP_HOST:?set FRONTEND_APP_HOST}`)"
      - "traefik.http.routers.${FRONTEND_APP_NAME:-manage-frontend}.entrypoints=websecure"
      - "traefik.http.routers.${FRONTEND_APP_NAME:-manage-frontend}.tls.certresolver=${CERT_RESOLVER:?set CERT_RESOLVER}"
      - "traefik.http.services.${FRONTEND_APP_NAME:-manage-frontend}.loadbalancer.server.port=${FRONTEND_APP_PORT:-80}"
    restart: unless-stopped

networks:
  web:
    external: true
