# 生产环境 Docker Compose 配置
# 使用方式: docker compose -f docker/docker-compose.yml -f docker/docker-compose.production.yml up -d

services:
  # ── Nginx 反代 + TLS 终端 ──
  nginx:
    image: nginx:1.27-alpine
    container_name: hms-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - nginx_logs:/var/log/nginx
    depends_on:
      app:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:80"]
      interval: 30s
      timeout: 5s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 128M
    networks:
      - hms-internal

  # ── HMS 应用服务器 ──
  app:
    build:
      context: ..
      dockerfile: Dockerfile
    container_name: hms-server
    restart: unless-stopped
    expose:
      - "3000"
      - "9090"
    env_file:
      - .env.production
    environment:
      ERP__DATABASE__URL: postgres://${POSTGRES_USER:-erp}:${POSTGRES_PASSWORD}@postgres:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-erp}
      ERP__REDIS__URL: redis://:${REDIS_PASSWORD}@redis:${REDIS_PORT:-6379}
    volumes:
      - app-uploads:/app/uploads
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/health"]
      interval: 30s
      timeout: 5s
      start_period: 60s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 1024M
        reservations:
          cpus: "0.5"
          memory: 256M
    networks:
      - hms-internal

  # ── 每日自动备份（含加密）──
  backup:
    image: postgres:16-alpine
    container_name: hms-backup
    restart: unless-stopped
    entrypoint: >
      sh -c "
        echo '$$BACKUP_CRON /usr/local/bin/backup.sh' > /etc/crontabs/root &&
        crond -f -l 2
      "
    environment:
      PGHOST: postgres
      PGPORT: "${POSTGRES_PORT:-5432}"
      PGUSER: "${POSTGRES_USER:-erp}"
      PGDATABASE: "${POSTGRES_DB:-erp}"
      BACKUP_DIR: /backups
      KEEP_DAYS: "${BACKUP_KEEP_DAYS:-7}"
      BACKUP_CRON: "${BACKUP_CRON:-0 2 * * *}"
      BACKUP_PASSPHRASE: "${BACKUP_PASSPHRASE:-}"
    volumes:
      - ./backup.sh:/usr/local/bin/backup.sh:ro
      - backup_data:/backups
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - hms-internal

  # ── uploads 文件备份（同步到宿主机）──
  uploads-backup:
    image: alpine:3.20
    container_name: hms-uploads-backup
    restart: unless-stopped
    entrypoint: >
      sh -c "
        echo '$$UPLOADS_BACKUP_CRON rsync -a --delete /source/uploads/ /backup/uploads/' > /etc/crontabs/root &&
        crond -f -l 2
      "
    environment:
      UPLOADS_BACKUP_CRON: "${UPLOADS_BACKUP_CRON:-0 3 * * *}"
    volumes:
      - app-uploads:/source/uploads:ro
      - uploads_backup_data:/backup/uploads
    networks:
      - hms-internal

  # ── Prometheus 监控 ──
  prometheus:
    image: prom/prometheus:v3.1.0
    container_name: hms-prometheus
    restart: unless-stopped
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.retention.time=30d"
      - "--storage.tsdb.retention.size=2GB"
      - "--web.enable-lifecycle"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./prometheus/alerts.yml:/etc/prometheus/alerts.yml:ro
      - prometheus_data:/prometheus
    expose:
      - "9090"
    networks:
      - hms-internal

  # ── Grafana 可视化 ──
  grafana:
    image: grafana/grafana:11.4.0
    container_name: hms-grafana
    restart: unless-stopped
    environment:
      GF_SECURITY_ADMIN_USER: "${GRAFANA_ADMIN_USER:-admin}"
      GF_SECURITY_ADMIN_PASSWORD: "${GRAFANA_ADMIN_PASSWORD:-}"
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_SERVER_ROOT_URL: "${GRAFANA_ROOT_URL:-http://localhost:3001}"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    expose:
      - "3000"
    depends_on:
      - prometheus
    networks:
      - hms-internal

volumes:
  app-uploads:
    driver: local
  backup_data:
    driver: local
  uploads_backup_data:
    driver: local
  nginx_logs:
    driver: local
  prometheus_data:
    driver: local
  grafana_data:
    driver: local

networks:
  hms-internal:
    driver: bridge
