203 lines
6.8 KiB
YAML
Executable File
203 lines
6.8 KiB
YAML
Executable File
# ===========================================
|
||
# 小虾剪辑 SaaS Docker Compose 配置
|
||
# ===========================================
|
||
#
|
||
# 用法:
|
||
# Staging: docker compose --env-file ../../.env -f compose.yml up -d
|
||
# Production: 设置相关环境变量后执行
|
||
#
|
||
# 环境变量说明:
|
||
# API_IMAGE - API 镜像名称 (默认: xiaoxia-saas-api:dev)
|
||
# WORKER_IMAGE - Worker 镜像名称 (默认: xiaoxia-saas-worker:dev)
|
||
# WEB_IMAGE - Web 镜像名称 (默认: xiaoxia-saas-web:dev)
|
||
# API_PORT - API 端口映射 (staging: 8000, production: 8001)
|
||
# WEB_PORT - Web 端口映射 (staging: 3001, production: 3002)
|
||
# GENERATED_FILES_HOST_DIR - 生成文件的主机目录
|
||
# GENERATION_CONCURRENCY - Generation worker 并发(用户实时任务,默认 2)
|
||
# TRANSCODE_CONCURRENCY - Transcode worker 并发(后台/转码/AI,默认 2)
|
||
# WORKER_MAX_TASKS_PER_CHILD - Worker 每个子进程最大任务数 (默认: 100)
|
||
# BEAT_ENABLED - 容器内启动 celery beat(默认 1;独立 beat 容器部署设为 0)
|
||
# WORKER_CONCURRENCY - 兼容旧变量:未显式设置上面两个并发时按此总数分配
|
||
#
|
||
# 重要:
|
||
# - 生产环境不要挂载 web-dist volume,否则会导致 403
|
||
# - 确保环境隔离网络已创建: docker network create xiaoxia-net-${ENV}
|
||
# - ENV=staging -> xiaoxia-net-staging
|
||
# - ENV=production -> xiaoxia-net-production
|
||
#
|
||
# #2073 队列分流:worker 容器内跑三个独立进程——beat(只发定时任务)、
|
||
# generation worker(只消费 generation 队列,实时高优)、transcode worker(消费
|
||
# transcode + celery 队列,后台任务)。beat 不再嵌入 generation worker,
|
||
# 不占实时任务槽位;TRANSCODE_CONCURRENCY 独立伸缩,不再依赖 WORKER_CONCURRENCY 差值。
|
||
|
||
# ===========================================
|
||
# 日志轮转配置(所有服务共享)
|
||
# ===========================================
|
||
x-logging: &default-logging
|
||
driver: json-file
|
||
options:
|
||
max-size: "50m"
|
||
max-file: "3"
|
||
|
||
services:
|
||
# =========================================
|
||
# API 服务
|
||
# =========================================
|
||
api:
|
||
image: ${API_IMAGE:-xiaoxia-saas-api:dev}
|
||
container_name: xiaoxia-api-${ENV:-staging}
|
||
restart: unless-stopped
|
||
stop_grace_period: 30s
|
||
stop_signal: SIGTERM
|
||
|
||
env_file:
|
||
- ../../.env
|
||
|
||
environment:
|
||
APP_ENV: ${APP_ENV:-staging}
|
||
GENERATED_FILES_DIR: /app/generated
|
||
GENERATED_FILES_URL_PREFIX: /generated-files
|
||
PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL:-https://api.xiaoxiajianji.com}
|
||
|
||
ports:
|
||
- "127.0.0.1:${API_PORT:-8000}:8000"
|
||
|
||
volumes:
|
||
- generated-files:/app/generated
|
||
- ../../deploy/configs:/app/configs:ro
|
||
|
||
networks:
|
||
- xiaoxia-net
|
||
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
|
||
logging: *default-logging
|
||
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '2.0'
|
||
memory: 2g
|
||
reservations:
|
||
cpus: '0.5'
|
||
memory: 512M
|
||
|
||
# =========================================
|
||
# Worker 服务(#2073 队列分流:beat + generation + transcode 同容器三进程)
|
||
# =========================================
|
||
# 三个进程独立启动,任一退出则容器整体退出由 docker restart 拉起;
|
||
# 各自的并发与资源占用通过环境变量控制:
|
||
# - generation:GENERATION_CONCURRENCY(默认 2),消费 generation 队列
|
||
# - transcode: TRANSCODE_CONCURRENCY(默认 2),消费 transcode,celery 队列
|
||
# - beat: 不消费任务,只发定时任务到 celery 默认队列
|
||
worker:
|
||
image: ${WORKER_IMAGE:-xiaoxia-saas-worker:dev}
|
||
|
||
container_name: xiaoxia-worker-${ENV:-staging}
|
||
restart: unless-stopped
|
||
# 长任务(ingest HEVC 转码最长 30min、生成硬超时 11min)给足优雅关闭窗口
|
||
stop_grace_period: 300s
|
||
stop_signal: SIGTERM
|
||
|
||
env_file:
|
||
- ../../.env
|
||
|
||
environment:
|
||
APP_ENV: ${APP_ENV:-staging}
|
||
# 兼容旧变量:若两个 *_CONCURRENCY 均未显式设置,entrypoint 会按此总数分配
|
||
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
|
||
WORKER_MAX_TASKS_PER_CHILD: ${WORKER_MAX_TASKS_PER_CHILD:-100}
|
||
# #2073 队列独立伸缩:generation 默认 2,transcode 默认 2(不再差值计算)
|
||
GENERATION_CONCURRENCY: ${GENERATION_CONCURRENCY:-2}
|
||
TRANSCODE_CONCURRENCY: ${TRANSCODE_CONCURRENCY:-2}
|
||
# beat 默认在本容器启动;独立 beat 容器部署时设为 0
|
||
BEAT_ENABLED: ${BEAT_ENABLED:-1}
|
||
GENERATED_FILES_DIR: /app/generated
|
||
GENERATED_FILES_URL_PREFIX: /generated-files
|
||
PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL:-https://api.xiaoxiajianji.com}
|
||
|
||
volumes:
|
||
- generated-files:/app/generated
|
||
|
||
networks:
|
||
- xiaoxia-net
|
||
|
||
# 健康检查:至少有一个 celery worker 进程在跑(beat 本身不作为存活依据)
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "grep -q 'celery.*worker' /proc/[0-9]*/cmdline 2>/dev/null || exit 1"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
|
||
logging: *default-logging
|
||
|
||
# 资源限制:容器总资源 = gen + trans + beat,按 2+2 并发场景建议 4C8G;
|
||
# 后续如需独立扩容/重启,可拆为 worker-generation / worker-transcode / worker-beat 三个 service。
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '4.0'
|
||
memory: 8g
|
||
reservations:
|
||
cpus: '1.0'
|
||
memory: 2G
|
||
|
||
# =========================================
|
||
# Web 服务(Nginx + 前端静态文件)
|
||
# =========================================
|
||
web:
|
||
image: ${WEB_IMAGE:-xiaoxia-saas-web:dev}
|
||
|
||
container_name: xiaoxia-web-${ENV:-staging}
|
||
restart: unless-stopped
|
||
|
||
ports:
|
||
- "127.0.0.1:${WEB_PORT:-3001}:80"
|
||
|
||
networks:
|
||
- xiaoxia-net
|
||
|
||
environment:
|
||
- APP_ENV=${ENV:-staging}
|
||
volumes:
|
||
- ./nginx-${ENV:-staging}.conf:/etc/nginx/conf.d/default.conf:ro
|
||
|
||
healthcheck:
|
||
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:80"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
logging: *default-logging
|
||
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '0.5'
|
||
memory: 512M
|
||
|
||
# ===========================================
|
||
# 共享卷配置
|
||
# ===========================================
|
||
volumes:
|
||
generated-files:
|
||
driver: local
|
||
driver_opts:
|
||
type: none
|
||
o: bind
|
||
device: ${GENERATED_FILES_HOST_DIR:?GENERATED_FILES_HOST_DIR must be set in .env}
|
||
|
||
# ===========================================
|
||
# 网络配置
|
||
# ===========================================
|
||
networks:
|
||
xiaoxia-net:
|
||
external: true
|
||
name: xiaoxia-net-${ENV:-staging}
|