version: '3.8' # Video Flow - Docker Compose 配置 # 支持水平扩展的视频处理服务 services: # ============================================================ # Redis - 消息队列和缓存 # ============================================================ redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped # ============================================================ # FastAPI Backend - API 服务 # ============================================================ api: build: context: . dockerfile: Dockerfile ports: - "8000:8000" volumes: - ./modules:/app/modules:ro - ./api:/app/api:ro - ./config.py:/app/config.py:ro - ./assets:/app/assets - ./output:/app/output - ./temp:/app/temp - ./video_flow.db:/app/video_flow.db # 方案A:通过 Unix Socket 连接宿主机 Postgres(不暴露 5432) - /var/run/postgresql:/var/run/postgresql # 复用 8502(/root/video-flow)生成的历史素材 - /root/video-flow/temp:/legacy/temp:ro - /root/video-flow/output:/legacy/output:ro environment: - REDIS_URL=redis://redis:6379/0 - PYTHONUNBUFFERED=1 # 8503 读写 8502 的 Postgres(从 .env 注入,避免写死密码) - DB_CONNECTION_STRING=${VIDEO_FLOW_DB_CONNECTION_STRING} depends_on: redis: condition: service_healthy command: uvicorn api.main:app --host 0.0.0.0 --port 8000 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped # ============================================================ # Celery Worker - 视频处理 Worker # 可以通过 docker-compose scale worker=N 水平扩展 # ============================================================ worker: build: context: . dockerfile: Dockerfile volumes: - ./modules:/app/modules:ro - ./api:/app/api:ro - ./config.py:/app/config.py:ro - ./bin:/app/bin:ro - ./assets:/app/assets - ./output:/app/output - ./temp:/app/temp - ./video_flow.db:/app/video_flow.db - /var/run/postgresql:/var/run/postgresql - /root/video-flow/temp:/legacy/temp:ro - /root/video-flow/output:/legacy/output:ro environment: - REDIS_URL=redis://redis:6379/0 - PYTHONUNBUFFERED=1 - C_FORCE_ROOT=1 - DB_CONNECTION_STRING=${VIDEO_FLOW_DB_CONNECTION_STRING} depends_on: redis: condition: service_healthy command: celery -A api.celery_app worker --loglevel=info --concurrency=2 -Q default,video,audio restart: unless-stopped deploy: # 生产环境可以增加副本数 replicas: 1 resources: limits: cpus: '2' memory: 4G # ============================================================ # React Frontend - 前端服务 (生产环境) # ============================================================ web: build: context: ./web dockerfile: Dockerfile ports: - "3000:80" depends_on: - api restart: unless-stopped # ============================================================ # Streamlit - 原有调试界面 (保留在 8503) # 连接到 8502 的数据目录,复用历史素材 # ============================================================ streamlit: build: context: . dockerfile: Dockerfile ports: # 默认对外保持 8502(兼容历史入口);容器内仍运行在 8503 - "${STREAMLIT_PORT:-8502}:8503" volumes: - ./app.py:/app/app.py:ro - ./modules:/app/modules:ro - ./config.py:/app/config.py:ro - ./assets:/app/assets - ./output:/app/output # 挂载 8502 服务的 temp 目录,复用历史项目数据 - /opt/gloda-factory/temp:/app/temp - ./video_flow.db:/app/video_flow.db - /var/run/postgresql:/var/run/postgresql - /root/video-flow/temp:/legacy/temp:ro - /root/video-flow/output:/legacy/output:ro environment: - PYTHONUNBUFFERED=1 - DB_CONNECTION_STRING=${VIDEO_FLOW_DB_CONNECTION_STRING} - WEB_BASE_URL=${WEB_BASE_URL} command: streamlit run app.py --server.port 8503 --server.address 0.0.0.0 restart: unless-stopped volumes: redis_data: networks: default: name: video-flow-network