# PAC 生产 compose — 单一真相在 apps/*/.env(跟 systemd 模式共用)
#
# 启动:
#   1. cp apps/pac-service/.env.example apps/pac-service/.env  并填好(POSTGRES_*/JWT_*/DEEPSEEK_*)
#   2. cp apps/pac-web/.env.example     apps/pac-web/.env      并填好(NEXT_PUBLIC_API_BASE_URL)
#   3. docker compose -f docker-compose.prod.yml \
#        --env-file apps/pac-service/.env \
#        --env-file apps/pac-web/.env \
#        up -d --build
#
#   说明:--env-file 给 compose CLI 做 ${VAR} 插值(POSTGRES_* / NEXT_PUBLIC_*);
#        env_file: 指令则把同一份文件注入容器内 process.env(JWT_* / DEEPSEEK_* 等)。
#        两者作用域不同,都要配。多个 --env-file 后者覆盖前者(本例无冲突 key)。
#
# 端口(宿主机):
#   postgres 5532 / redis 6479 / pac-service 3101 / pac-web 3100
#
# 内部网络:容器之间用服务名访问(postgres:5432 / redis:6379),容器内 port 用 image 默认

services:
  postgres:
    image: postgres:16-alpine
    restart: always
    env_file: ./apps/pac-service/.env   # 读 POSTGRES_USER/PASSWORD/DB
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5532:5432"           # 宿主仅本地访问(psql 进容器调试用)
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-pac}"]
      interval: 10s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: always
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis_data:/data
    ports:
      - "127.0.0.1:6479:6379"

  # One-shot migrator: applies pending Prisma migrations and exits.
  # Runs before pac-service so the schema is current before any traffic
  # hits the API. Safe to re-run — `migrate deploy` is idempotent.
  pac-migrate:
    build:
      context: .
      dockerfile: apps/pac-service/Dockerfile
      target: prod
    restart: "no"
    depends_on:
      postgres:
        condition: service_healthy
    env_file: ./apps/pac-service/.env
    environment:
      # 覆盖 .env 里 host=localhost 的连接串 → 走 docker 内部网络
      DATABASE_URL: postgresql://${POSTGRES_USER:-pac}:${POSTGRES_PASSWORD:-pac}@postgres:5432/${POSTGRES_DB:-pac}?schema=public
    working_dir: /app/apps/pac-service
    command: ["npx", "prisma", "migrate", "deploy"]

  pac-service:
    build:
      context: .
      dockerfile: apps/pac-service/Dockerfile
      target: prod
    restart: always
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
      pac-migrate:
        condition: service_completed_successfully
    env_file: ./apps/pac-service/.env
    environment:
      NODE_ENV: production
      PORT: 3101
      # 覆盖 .env 的 localhost URL → 走 docker 内部网络
      DATABASE_URL: postgresql://${POSTGRES_USER:-pac}:${POSTGRES_PASSWORD:-pac}@postgres:5432/${POSTGRES_DB:-pac}?schema=public
      REDIS_URL: redis://redis:6379
      # 语音听写 ASR(自部署 SenseVoice,内网)
      PAC_ASR_URL: http://pac-asr:8000
    ports:
      - "127.0.0.1:3101:3101"

  # 语音听写 ASR — SenseVoice-small(CPU)。模型不进镜像:
  #   服务器准备 ${PAC_MODELS_DIR:-../pac-models}/sensevoice/{model.int8.onnx,tokens.txt}
  pac-asr:
    build:
      context: .
      dockerfile: apps/asr-sensevoice/Dockerfile
      args:
        # 服务器在阿里云 — 用国内镜像源提速
        PIP_INDEX_URL: https://mirrors.aliyun.com/pypi/simple
        DEBIAN_MIRROR: mirrors.aliyun.com
    restart: always
    volumes:
      - ${PAC_MODELS_DIR:-../pac-models}/sensevoice:/models/sensevoice:ro
    # 不发布端口 — 仅 compose 内网供 pac-service 调用(无鉴权)
    cpus: 2
    mem_limit: 2g

  pac-web:
    build:
      context: .
      dockerfile: apps/pac-web/Dockerfile
      target: prod
      args:
        # build-time inline 进客户端 bundle,改了必须 --build
        # 来自 apps/pac-web/.env(启动时用 --env-file 指定那份)
        NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL}
    restart: always
    depends_on:
      - pac-service
    env_file: ./apps/pac-web/.env
    environment:
      NODE_ENV: production
      PORT: 3100
    ports:
      - "127.0.0.1:3100:3100"

volumes:
  postgres_data:
  redis_data:
