296 lines
7.2 KiB
Markdown
296 lines
7.2 KiB
Markdown
# 部署指南
|
||
|
||
本项目使用 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
|
||
```
|