# 部署指南 本项目使用 Docker + docker-compose 管理多环境部署。所有配置通过环境变量注入,`load_dotenv(override=False)` 保证**真实环境变量(容器/CI/CD 注入)永远优先于 `.env` 文件**。 --- ## 文件结构 ``` backend/ ├── Dockerfile # 多阶段构建镜像(共用) ├── docker-compose.yml # 基础配置(生产默认) ├── docker-compose.dev.yml # 开发环境 override ├── docker-compose.staging.yml # 测试环境 override ├── .env # 本地开发配置(不提交 git) ├── .env.staging # 测试环境配置模板(不提交真实密钥) └── .env.example # 全量变量说明(提交 git) ``` --- ## 三个环境对比 | 项目 | 开发 (dev) | 测试 (staging) | 生产 (production) | |------|-----------|---------------|------------------| | 启动方式 | uv 直接运行 或 Docker | docker-compose + override | Docker 镜像 + CI/CD | | 配置来源 | `.env` | `.env.staging` | 平台注入环境变量 | | `LOG_LEVEL` | `DEBUG` | `INFO` | `WARNING` | | `--reload` | 是 | 否 | 否 | | `restart` | no | unless-stopped | unless-stopped | | `.env` 文件 | 挂载 / 读取 | 挂载 `.env.staging` | **不挂载任何文件** | --- ## 开发环境 ### 方式一:直接用 uv(推荐,最快) ```bash cd backend uv run uvicorn server:app --host 0.0.0.0 --port 3001 --reload ``` 自动读取 `.env`,支持热重载。 ### 方式二:Docker + dev override ```bash cd backend docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build ``` 源码目录挂载进容器,修改文件自动重载,行为与方式一一致,但运行在容器内。 --- ## 测试环境 (Staging) ### 服务器目录约定 项目统一放在 `/opt` 下,这是 Linux 存放第三方应用的标准位置,权限独立、路径固定: ```bash /opt/aigc-demo/ # 项目根目录 └── backend/ # Python 后端(本文档所描述的部分) ``` 初次登录服务器后执行: ```bash sudo mkdir -p /opt/aigc-demo sudo chown $USER:$USER /opt/aigc-demo ``` ### 第一步:服务器安装 Docker ```bash # Ubuntu / Debian curl -fsSL https://get.docker.com | sh sudo systemctl enable --now docker # CentOS / AlmaLinux sudo yum install -y docker sudo systemctl enable --now docker # 验证 docker --version docker compose version ``` ### 第二步:拉取代码 ```bash cd /opt/aigc-demo git clone https://github.com/your-repo/rtc-aigc-demo.git . # 或者已有仓库时更新 git pull ``` 如果服务器没有配置 git,也可以从本机传: ```bash # 本机执行 scp -r ./backend user@your-server-ip:/opt/aigc-demo/ ``` ### 第三步:配置 staging 密钥 ```bash cd /opt/aigc-demo/backend cp .env.staging .env.staging.local vim .env.staging.local ``` **必填项:** ```bash CUSTOM_ACCESS_KEY_ID=你的火山引擎AK CUSTOM_SECRET_KEY=你的火山引擎SK CUSTOM_RTC_APP_ID=你的RTC AppId CUSTOM_RTC_APP_KEY=你的RTC AppKey CUSTOM_TASK_ID=你的TaskId CUSTOM_AGENT_USER_ID=你的AgentUserId LOCAL_LLM_API_KEY=你的Ark API Key LOCAL_LLM_MODEL=你的Ark端点ID # 关键:填服务器公网 IP 或域名 CUSTOM_LLM_URL=http://你的公网IP:3001/v1/api/chat_callback # 有域名 + HTTPS 则改为: # CUSTOM_LLM_URL=https://your-staging-domain.example.com/v1/api/chat_callback ``` > 火山引擎 RTC 平台需要能主动回调 `CUSTOM_LLM_URL`,所以这里必须填**公网地址**,localhost 无效。 ### 第四步:开放防火墙端口 在云平台控制台的**安全组**放行 `3001` 端口(入方向,TCP): - **阿里云**:`ECS 控制台 → 安全组 → 配置规则 → 添加入方向规则 → 端口 3001` - **腾讯云**:`CVM 控制台 → 安全组 → 添加规则 → 端口 3001` ### 第五步:启动服务 ```bash cd /opt/aigc-demo/backend docker compose -f docker-compose.yml -f docker-compose.staging.yml \ --env-file .env.staging.local up -d --build ``` `-d` 后台运行,`--build` 每次重新构建镜像。 ### 第六步:验证 ```bash # 容器内健康检查 curl http://localhost:3001/health # 预期:{"status":"ok"} # 从外网验证(换成你的公网 IP) curl http://你的公网IP:3001/health # 查看实时日志 docker compose logs -f backend ``` ### 日常运维命令 ```bash # 更新代码后重新部署 git pull docker compose -f docker-compose.yml -f docker-compose.staging.yml \ --env-file .env.staging.local up -d --build # 重启服务 docker compose -f docker-compose.yml -f docker-compose.staging.yml restart # 停止服务 docker compose -f docker-compose.yml -f docker-compose.staging.yml down # 查看最近 100 行日志 docker compose logs --tail=100 backend ``` --- ## 生产环境 ### 构建镜像 ```bash cd backend # 打带版本号的 tag(用 git commit hash) IMAGE_TAG=$(git rev-parse --short HEAD) docker build -t aigc-backend:${IMAGE_TAG} . docker build -t aigc-backend:latest . ``` ### 推送到镜像仓库 ```bash # 以阿里云 ACR 为例 docker tag aigc-backend:${IMAGE_TAG} registry.cn-beijing.aliyuncs.com/your-ns/aigc-backend:${IMAGE_TAG} docker push registry.cn-beijing.aliyuncs.com/your-ns/aigc-backend:${IMAGE_TAG} ``` ### 运行 生产环境**不使用任何 `.env` 文件**,所有密钥由平台(ECS 环境变量、K8s Secret、Cloud Run)注入: ```bash docker run -d \ --name aigc-backend \ --restart unless-stopped \ -p 3001:3001 \ -e CUSTOM_ACCESS_KEY_ID=xxx \ -e CUSTOM_SECRET_KEY=xxx \ -e LOCAL_LLM_API_KEY=xxx \ -e LOG_LEVEL=warning \ # ... 其余变量 ... aigc-backend:${IMAGE_TAG} ``` 或通过 `--env-file` 传入一个**不在代码仓库中**的生产密钥文件: ```bash docker run -d --env-file /secure/prod.env -p 3001:3001 aigc-backend:${IMAGE_TAG} ``` --- ## 负载均衡 / 反向代理注意事项 | 要求 | 原因 | |------|------| | idle timeout ≥ 75s | 容器 `--timeout-keep-alive 75`,LB 超时需更长 | | 关闭响应缓冲 | `/api/chat_callback` 是 SSE 流式响应,Nginx 需设 `proxy_buffering off` | | TLS 在 LB 层终止 | 容器内不处理 HTTPS | | 健康检查路径 `GET /health` | 返回 `{"status":"ok"}`,HTTP 200 | | sticky session(如需水平扩展)| 会话存储在内存中,同一客户端需路由到同一容器 | Nginx 反向代理最小配置片段: ```nginx location /v1/api/chat_callback { proxy_pass http://backend:3001; proxy_buffering off; proxy_cache off; proxy_set_header X-Forwarded-For $remote_addr; } location / { proxy_pass http://backend:3001; proxy_set_header X-Forwarded-For $remote_addr; } ``` --- ## .gitignore 建议 确保以下文件不进入版本库: ```gitignore .env .env.staging.local .env.production *.local ``` `.env.staging`(仅含占位符的模板)可以提交,便于团队成员了解需要配置哪些变量。 --- ## 快速参考 ```bash # 开发 uv run uvicorn server:app --reload # 测试环境(Docker) docker compose -f docker-compose.yml -f docker-compose.staging.yml up --build # 生产镜像构建 docker build -t aigc-backend:$(git rev-parse --short HEAD) . # 查看健康状态 curl http://localhost:3001/health # 查看容器日志 docker compose logs -f backend ```