Files
ai-video-fullstack/docker-compose.yaml
Xin Wang e857828fe5 Add WebRTC TURN configuration and related enhancements
- Introduce a new `.env.example` file for environment variable setup, including `PUBLIC_IP`, `TURN_SECRET`, and `TURN_URLS` for WebRTC TURN server configuration.
- Update `docker-compose.yaml` to support TURN server deployment with necessary environment variables and commands.
- Enhance backend configuration and routes to include WebRTC ICE server settings, allowing for STUN/TURN server integration.
- Implement a new service for managing WebRTC ICE server configurations, providing credentials for TURN when configured.
- Modify frontend API to fetch ICE server configurations dynamically, improving support for cross-network voice preview.
2026-07-06 17:45:53 +08:00

164 lines
5.5 KiB
YAML

# AI Video Assistant 平台 —— docker compose
#
# 核心服务(默认起):postgres + api + ui
# docker compose up -d postgres api # 后端 + 库
# docker compose up -d # 再带上前端 ui → http://localhost:3030
#
# 语音对话调试(参考 dograh quick start 的直连方案):
# docker compose up -d && make db-seed # 首次需灌种子(凭证+助手)
# 浏览器开 http://localhost:3030 → 助手 → 语音预览
# (localhost 是 secure context,麦克风可用;WebRTC 媒体直连 api,WS 信令走 :8000)
#
# 可选服务(用 profile 推迟到需要时):
# docker compose --profile data up -d # + redis / rustfs(后台任务、S3 录音存储)
# docker compose --profile remote up -d # + coturn(WebRTC 公网 TURN 穿透)
services:
# ---- 数据库(api 强依赖,默认起) ----
postgres:
image: pgvector/pgvector:pg17
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-postgres}"
POSTGRES_DB: postgres
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 3s
timeout: 3s
retries: 10
networks: [app-network]
# ---- 后端引擎(pipecat:WebRTC + WS 双输出) ----
api:
build: ./backend
# 调试:挂源码 + --reload,改代码即时生效,无需重建镜像
command: uvicorn app:app --host 0.0.0.0 --port 8000 --reload
volumes:
- ./backend:/app
- /app/.venv # 屏蔽宿主机的 venv(容器用镜像内的依赖)
- /app/__pycache__
env_file:
- path: ./backend/.env
required: false
environment:
# 容器内连库:用服务名 postgres,覆盖 .env 里的 localhost
DATABASE_URL: "postgresql+asyncpg://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/postgres"
# 3030 = docker ui 宿主端口;3000 = 宿主机裸跑 npm run dev 时的端口
CORS_ORIGINS: "http://localhost:3030,http://127.0.0.1:3030,http://localhost:3000,http://127.0.0.1:3000"
# WebRTC TURN(公网部署:设 PUBLIC_IP + TURN_SECRET,并 docker compose --profile remote up)
TURN_URLS: "${TURN_URLS:-}"
TURN_SECRET: "${TURN_SECRET:-}"
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "python -c \"import urllib.request;urllib.request.urlopen('http://localhost:8000/health')\""]
interval: 15s
timeout: 5s
retries: 5
start_period: 40s
networks: [app-network]
# ---- 前端(dev 模式,挂源码带 HMR;发布时再做生产构建) ----
ui:
image: node:22-slim
working_dir: /app
command: sh -c "npm install && npm run dev"
environment:
NEXT_PUBLIC_API_BASE_URL: "http://localhost:8000"
volumes:
- ./frontend:/app
- /app/node_modules
ports:
# 宿主机用 3030 访问(容器内 next dev 仍监听 3000),避开本地裸跑前端的 3000
- "3030:3000"
depends_on:
- api
networks: [app-network]
# ---- 可选(profile: data):后台任务 / 录音存储 ----
redis:
image: redis:7
profiles: ["data"]
command: ["--requirepass", "redissecret"]
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks: [app-network]
# RustFS:S3 兼容对象存储(MinIO 替代,Rust 实现)
# 9000 = S3 API,9001 = Web 控制台。默认账号 rustfsadmin/rustfsadmin。
rustfs:
image: rustfs/rustfs:latest
profiles: ["data"]
environment:
RUSTFS_VOLUMES: /data # 单盘单节点(开发够用)
RUSTFS_ADDRESS: 0.0.0.0:9000 # S3 API
RUSTFS_CONSOLE_ADDRESS: 0.0.0.0:9001 # 控制台
RUSTFS_CONSOLE_ENABLE: "true"
RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS: "*"
# 凭证:首次初始化后写入数据卷。改 ak/sk 需先清空 rustfs-data 卷再重起。
RUSTFS_ACCESS_KEY: "${S3_ACCESS_KEY:-rustfsadmin}"
RUSTFS_SECRET_KEY: "${S3_SECRET_KEY:-rustfsadmin}"
ports:
- "127.0.0.1:9000:9000"
- "127.0.0.1:9001:9001"
volumes:
- rustfs-data:/data
networks: [app-network]
# ---- 可选(profile: remote):WebRTC 公网穿透 ----
# 在项目根 .env 设置 PUBLIC_IP(云主机公网 IP)与 TURN_SECRET,与 backend TURN_SECRET 一致。
# 云安全组放行:UDP/TCP 3478,UDP 49152-49200。
coturn:
image: coturn/coturn:4.8.0
profiles: ["remote"]
network_mode: host
command:
- -n
- --log-file=stdout
- --listening-port=3478
- --listening-ip=0.0.0.0
- --external-ip=${PUBLIC_IP:?set PUBLIC_IP in .env for coturn}
- --realm=ai-video
- --use-auth-secret
- --static-auth-secret=${TURN_SECRET:-changeme}
- --min-port=49152
- --max-port=49200
- --no-cli
# ---- 可选(profile: tls):nginx 反代统一 TLS,局域网 https 调试语音预览 ----
# 起前先生成证书:./deploy/setup-certs.sh(证书落在 deploy/certs/)
# docker compose --profile tls up -d
# 浏览器 → https://localhost 或 https://<本机IP>
nginx:
image: nginx:alpine
profiles: ["tls"]
ports:
- "80:80"
- "443:443"
volumes:
# 整份配置当作 nginx.conf 加载(容器内 proxy_pass 用服务名 api/ui)
- ./deploy/nginx/ai-video.docker.conf:/etc/nginx/nginx.conf:ro
- ./deploy/certs:/etc/nginx/certs:ro
depends_on:
- api
- ui
networks: [app-network]
volumes:
postgres_data:
redis_data:
rustfs-data:
networks:
app-network:
driver: bridge