# ============================================================================= # 美家卡智影 API - 生产环境配置 # ============================================================================= # 说明: # • 此配置仅运行 api + scheduler 服务 # • 假设 PostgreSQL 和 Redis 由外部基础设施提供(云数据库 / 自建集群) # • 与测试环境使用**同一套 Dockerfile**,仅环境变量不同 # # 用法: # export $(cat .env | xargs) # 或从 CI/CD / 密钥管理注入 # docker compose -f docker-compose.prod.yml up -d --build # ============================================================================= services: api: build: context: . dockerfile: Dockerfile container_name: meijiaka-zy-api environment: - ENV=production - APP_BASE_URL=https://tapi.meijiaka.cn - DEBUG=false - LOG_LEVEL=INFO - DATABASE_URL=${DATABASE_URL} - REDIS_HOST=${REDIS_HOST} - REDIS_PORT=${REDIS_PORT:-6379} - REDIS_DB=${REDIS_DB:-0} - SECRET_KEY=${SECRET_KEY} - VOLCENGINE_API_KEY=${VOLCENGINE_API_KEY} - VIDU_API_KEY=${VIDU_API_KEY} - QINIU_ACCESS_KEY=${QINIU_ACCESS_KEY} - QINIU_SECRET_KEY=${QINIU_SECRET_KEY} volumes: # 仅持久化日志到宿主机,其他数据走对象存储 - /opt/meijiaka-zy/logs:/root/Documents/Meijiaka-zy/logs command: alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 ports: - "8000:8000" restart: unless-stopped healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""] interval: 30s timeout: 10s retries: 3 start_period: 30s scheduler: build: context: . dockerfile: Dockerfile container_name: meijiaka-zy-scheduler environment: - ENV=production - APP_BASE_URL=https://tapi.meijiaka.cn - DEBUG=false - LOG_LEVEL=INFO - DATABASE_URL=${DATABASE_URL} - REDIS_HOST=${REDIS_HOST} - REDIS_PORT=${REDIS_PORT:-6379} - REDIS_DB=${REDIS_DB:-0} - SECRET_KEY=${SECRET_KEY} - VOLCENGINE_API_KEY=${VOLCENGINE_API_KEY} - VIDU_API_KEY=${VIDU_API_KEY} volumes: - /opt/meijiaka-zy/logs:/root/Documents/Meijiaka-zy/logs command: python -m app.scheduler.main restart: unless-stopped healthcheck: test: ["CMD-SHELL", "python -c \"import asyncio, time; from app.core.redis_client import get_redis_client; r=get_redis_client(); t=asyncio.run(r.get('scheduler:heartbeat')); t=float(t) if t else 0; assert t>0 and time.time()-t<30, 'scheduler heartbeat stale'\""] interval: 30s timeout: 10s retries: 3 start_period: 30s depends_on: api: condition: service_healthy