From 3eb7e6c4d85bdc87c623c1b8d3ad69ec6580081a Mon Sep 17 00:00:00 2001 From: cc <94575594@qq.com> Date: Tue, 31 Mar 2026 11:05:29 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEPLOY.md | 530 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 501 insertions(+), 29 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index 23647da..d064fa5 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -3,8 +3,12 @@ ## 项目概述 - **项目名称**:AI 英语学习辅助平台 -- **技术栈**:Vue 3 + Vite + Vue Router(History 模式) -- **构建产物**:纯静态文件(HTML / CSS / JS),可部署到任意静态托管服务 +- **技术栈**: + - 前端:Vue 3 + Vite + Vue Router(History 模式) + - 后端:Express.js + FFmpeg(视频合成服务) +- **项目结构**: + - 前端:纯静态文件(HTML / CSS / JS),可部署到任意静态托管服务 + - 后端:Node.js 服务,需要 FFmpeg 环境,提供视频合成 API --- @@ -12,21 +16,63 @@ ### 1.1 环境要求 -| 工具 | 版本要求 | -|------|----------| -| Node.js | >= 18.x(推荐 20.x LTS) | -| npm | >= 9.x | +| 工具 | 版本要求 | 用途 | +|------|----------|------| +| Node.js | >= 18.x(推荐 20.x LTS) | 前端构建 & 后端服务运行 | +| npm | >= 9.x | 包管理器 | +| FFmpeg | 最新稳定版 | 后端视频合成(仅后端服务需要) | ```bash +# 检查 Node.js 和 npm 版本 node -v npm -v + +# 检查 FFmpeg 是否已安装(后端服务需要) +ffmpeg -version ``` -### 1.2 安装依赖 +### 1.2 安装 FFmpeg(后端服务必需) + +#### Windows + +1. 下载 FFmpeg: https://www.gyan.dev/ffmpeg/builds/ +2. 解压到 `C:\ffmpeg` +3. 添加 `C:\ffmpeg\bin` 到系统环境变量 PATH +4. 验证安装: + ```bash + ffmpeg -version + ``` + +#### macOS ```bash +# 使用 Homebrew 安装 +brew install ffmpeg + +# 验证安装 +ffmpeg -version +``` + +#### Linux (Ubuntu/Debian) + +```bash +# 安装 FFmpeg +sudo apt update && sudo apt install ffmpeg + +# 验证安装 +ffmpeg -version +``` + +### 1.3 安装依赖 + +```bash +# 安装前端依赖 cd AI_Demo npm install + +# 安装后端依赖 +cd server +npm install ``` --- @@ -63,12 +109,15 @@ Cross-Origin-Embedder-Policy: require-corp 项目在开发环境通过 Vite 代理转发以下 API 请求,**生产环境必须在服务器/网关层配置对应的反向代理**: -| 前端请求路径前缀 | 代理目标 | 用途 | -|-----------------|----------|------| -| `/tts-api` | `https://openspeech.bytedance.com` | 豆包 TTS 语音合成 | -| `/ark-api` | `https://ark.cn-beijing.volces.com` | 火山引擎 Ark 大模型 | -| `/dashscope-api` | `https://dashscope.aliyuncs.com` | 阿里云百炼 | -| `/asr-ws` | `wss://openspeech.bytedance.com` | 豆包 ASR WebSocket | +| 前端请求路径前缀 | 代理目标 | 用途 | 备注 | +|-----------------|----------|------|------| +| `/api/video` | 后端服务(默认 http://localhost:3001) | 视频合成 | **无需跨域代理**,直接访问后端服务 | +| `/tts-api` | `https://openspeech.bytedance.com` | 豆包 TTS 语音合成 | 需要反向代理 | +| `/ark-api` | `https://ark.cn-beijing.volces.com` | 火山引擎 Ark 大模型 | 需要反向代理 | +| `/dashscope-api` | `https://dashscope.aliyuncs.com` | 阿里云百炼 | 需要反向代理 | +| `/asr-ws` | `wss://openspeech.bytedance.com` | 豆包 ASR WebSocket | 需要反向代理+注入鉴权 Header | + +> **后端服务说明**:`/api/video` 接口由本项目的后端服务(`server/`)提供,不需要跨域代理,但需要确保后端服务正常运行。 > **ASR WebSocket 特殊说明**:`/asr-ws` 代理需要在代理层注入以下鉴权 Header(浏览器原生 WebSocket 不支持自定义 Header): > - `X-Api-App-Key` @@ -80,6 +129,8 @@ Cross-Origin-Embedder-Policy: require-corp ## 三、构建生产包 +### 3.1 前端构建 + ```bash npm run build ``` @@ -101,6 +152,22 @@ dist/ npm run preview ``` +### 3.2 后端服务准备 + +后端服务无需构建,直接使用源码运行即可。确保: + +1. 已安装 FFmpeg(见 1.2 节) +2. 已安装依赖: + ```bash + cd server + npm install + ``` +3. 测试服务是否正常: + ```bash + npm start + ``` + 访问 http://localhost:3001/health 应返回 `{"status":"ok"}` + --- ## 四、部署方案 @@ -136,6 +203,26 @@ server { try_files $uri $uri/ /index.html; } + # 后端视频合成服务代理 + location /api/video/ { + proxy_pass http://localhost:3001/api/video/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # 增大请求体大小限制(视频合成可能需要) + client_max_body_size 100m; + + # 增加超时时间(视频合成耗时较长) + proxy_connect_timeout 300; + proxy_send_timeout 300; + proxy_read_timeout 300; + } + # 代理:豆包 TTS location /tts-api/ { proxy_pass https://openspeech.bytedance.com/; @@ -180,6 +267,7 @@ server { } } ``` +``` #### 4.A.3 启用配置并重启 Nginx @@ -194,7 +282,34 @@ nginx -t systemctl reload nginx ``` -#### 4.A.4 配置 HTTPS(推荐) +#### 4.A.4 启动后端服务 + +后端服务需要使用进程管理器(如 PM2)保持持续运行: + +```bash +# 安装 PM2(如果未安装) +npm install -g pm2 + +# 进入后端目录 +cd /path/to/AI_Demo/server + +# 启动后端服务 +pm2 start index.js --name ai-demo-server + +# 查看服务状态 +pm2 status + +# 查看日志 +pm2 logs ai-demo-server + +# 设置开机自启 +pm2 startup +pm2 save +``` + +后端服务将在 `http://localhost:3001` 启动,Nginx 会将 `/api/video` 请求代理到该端口。 + +#### 4.A.5 配置 HTTPS(推荐) ```bash # 使用 Certbot 申请免费 SSL 证书 @@ -204,17 +319,34 @@ certbot --nginx -d your-domain.com --- -### 方案 B:Node.js + Express 静态服务器 +### 方案 B:Node.js + Express 部署(前后端分离) -适用于需要在 Node.js 环境中自定义响应头的场景。 +适用于需要在 Node.js 环境中自定义响应头的场景,前后端独立部署。 -#### 4.B.1 安装依赖 +#### 4.B.1 后端服务部署 + +后端服务已在 `server/` 目录中,需要独立运行: ```bash -npm install express http-proxy-middleware +# 进入后端目录 +cd server + +# 安装依赖 +npm install + +# 使用 PM2 启动服务 +pm2 start index.js --name ai-demo-backend + +# 设置开机自启 +pm2 startup +pm2 save ``` -#### 4.B.2 创建服务器文件 `server.js` +后端服务将在 `http://localhost:3001` 启动。 + +#### 4.B.2 前端静态服务器 + +创建前端静态服务器文件 `frontend-server.js`(项目根目录): ```js import express from 'express' @@ -234,7 +366,14 @@ app.use((req, res, next) => { next() }) -// API 代理 +// 后端视频合成服务代理 +app.use('/api/video', createProxyMiddleware({ + target: 'http://localhost:3001', + changeOrigin: true, + timeout: 300000, // 5分钟超时 +})) + +// 第三方 API 代理 app.use('/tts-api', createProxyMiddleware({ target: 'https://openspeech.bytedance.com', changeOrigin: true, @@ -277,16 +416,35 @@ app.get('*', (req, res) => { }) app.listen(PORT, () => { - console.log(`Server running at http://localhost:${PORT}`) + console.log(`Frontend server running at http://localhost:${PORT}`) + console.log(`Backend API: http://localhost:3001`) }) ``` -#### 4.B.3 启动服务 +#### 4.B.3 安装前端服务器依赖 ```bash -DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx node server.js +# 在项目根目录安装 +npm install express http-proxy-middleware ``` +#### 4.B.4 启动前端服务器 + +```bash +# 在项目根目录启动 +DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx pm2 start frontend-server.js --name ai-demo-frontend + +# 查看两个服务的状态 +pm2 status + +# 设置开机自启 +pm2 save +``` + +现在有两个服务运行: +- **前端服务**:`http://localhost:3000`(提供静态文件和代理) +- **后端服务**:`http://localhost:3001`(视频合成 API) + --- ### 方案 C:EdgeOne Pages / Vercel / Netlify(纯静态托管) @@ -320,9 +478,20 @@ DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx node server.js ## 五、部署后验证清单 +### 5.1 后端服务验证 + +| 验证项 | 检查方法 | 预期结果 | +|--------|----------|----------| +| 后端服务运行 | `pm2 status` 或 `ps aux \| grep node` | 显示 ai-demo-server 进程 | +| 健康检查接口 | `curl http://localhost:3001/health` | 返回 `{"status":"ok"}` | +| FFmpeg 可用 | `curl http://localhost:3001/api/video/health` | 返回 `{"status":"ok","message":"视频合成服务正常运行"}` | +| 后端日志无错误 | `pm2 logs ai-demo-server` | 无报错信息 | + +### 5.2 前端服务验证 + | 验证项 | 检查方法 | |--------|----------| -| 页面正常加载 | 访问首页,确认 6 个功能卡片显示正常 | +| 页面正常加载 | 访问首页,确认功能卡片显示正常 | | 路由刷新不 404 | 直接访问 `/pronunciation`、`/speaking` 等子路由 | | COOP/COEP 响应头 | 浏览器 DevTools → Network → 查看 index.html 响应头 | | TTS 语音合成 | 进入发音练习页,测试语音播放 | @@ -331,6 +500,13 @@ DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx node server.js | 试题分析 | 进入试题分析页,上传图片或输入题目 | | 单词拼写练习 | 进入单词拼写页,测试拼写检测功能 | +### 5.3 视频合成功能验证 + +| 验证项 | 检查方法 | +|--------|----------| +| 前端可访问后端 | 浏览器 Network 标签查看 `/api/video/health` 请求 | +| 视频合成接口 | 在试题分析页生成视频讲解,检查是否能正常下载 | + --- ## 六、常见问题排查 @@ -355,7 +531,29 @@ DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx node server.js **原因**:代理未注入豆包 ASR 鉴权 Header,或 WebSocket 升级配置缺失。 **解决**:确认 Nginx 配置中包含 `proxy_set_header Upgrade $http_upgrade;` 及三个 `X-Api-*` Header。 -### Q5:构建时内存不足 +### Q5:视频合成失败或接口 504 超时 + +**原因**:视频合成耗时较长,默认代理超时时间不足,或后端服务未启动。 +**解决**: +1. 检查后端服务是否运行:`pm2 status` 或 `curl http://localhost:3001/health` +2. 检查 FFmpeg 是否安装:`ffmpeg -version` +3. 增加 Nginx 超时时间(已在配置中设置为 300 秒) +4. 查看后端日志:`pm2 logs ai-demo-server` + +### Q6:后端服务启动失败:`FFmpeg not found` + +**原因**:系统未安装 FFmpeg 或未添加到环境变量。 +**解决**:参考第一节 1.2,安装 FFmpeg 并配置环境变量。 + +### Q7:视频合成返回 `Internal server error` + +**原因**:可能是 FFmpeg 处理错误、临时目录权限问题或资源下载失败。 +**解决**: +1. 查看后端详细日志:`pm2 logs ai-demo-server` +2. 检查 `server/temp/` 目录权限:`ls -la server/temp` +3. 测试后端健康检查:`curl http://localhost:3001/api/video/health` + +### Q8:构建时内存不足 **原因**:项目包含 FFmpeg WASM,构建产物较大。 **解决**: @@ -377,11 +575,18 @@ NODE_OPTIONS=--max-old-space-size=4096 npm run build | `/essay-correction` | 作文批改 | 图片/文本作文批改 | | `/exam-analysis` | 试题分析 | 图片题目分析解答 | | `/spell-practice` | 单词拼写 | 单词拼写练习检测 | +| `/problem-solving` | 解题指导 | AI 解题步骤指导 | +| `/question-generator` | 题目生成 | 自动生成练习题 | +| `/question-variant` | 题目变体 | 生成相似题目变体 | +| `/audio-to-text` | 语音转文字 | 音频转文本功能 | +| `/question-explanation` | 视频讲解 | 视频合成讲解(使用后端服务)| --- ## 八、依赖版本参考 +### 前端依赖(package.json) + | 依赖包 | 版本 | |--------|------| | vue | ^3.5.30 | @@ -393,14 +598,31 @@ NODE_OPTIONS=--max-old-space-size=4096 npm run build | marked | ^17.0.5 | | pako | ^2.1.0 | +### 后端依赖(server/package.json) + +| 依赖包 | 版本 | 用途 | +|--------|------|------| +| express | ^4.21.0 | Web 服务器框架 | +| cors | ^2.8.5 | 跨域中间件 | +| fluent-ffmpeg | ^2.1.3 | FFmpeg Node.js 封装 | +| axios | ^1.7.0 | HTTP 客户端 | +| uuid | ^10.0.0 | UUID 生成 | + --- ## 九、目录结构参考 ``` AI_Demo/ -├── dist/ # 构建产物(部署此目录) -├── src/ +├── dist/ # 前端构建产物(部署此目录) +├── server/ # 后端服务 +│ ├── routes/ # 路由模块 +│ │ └── video.js # 视频合成 API +│ ├── temp/ # 临时文件目录(自动创建) +│ ├── index.js # 后端服务入口 +│ ├── package.json # 后端依赖配置 +│ └── README.md # 后端服务文档 +├── src/ # 前端源码 │ ├── config/index.js # API 密钥配置(部署前确认) │ ├── router/index.js # 路由定义 │ ├── views/ # 页面组件 @@ -409,11 +631,261 @@ AI_Demo/ │ │ ├── Speaking.vue # 口语对话 │ │ ├── EssayCorrection.vue # 作文批改 │ │ ├── ExamAnalysis.vue # 试题分析 -│ │ └── SpellPractice.vue # 单词拼写 +│ │ ├── SpellPractice.vue # 单词拼写 +│ │ ├── ProblemSolving.vue # 解题指导 +│ │ ├── QuestionGenerator.vue # 题目生成 +│ │ ├── QuestionVariant.vue # 题目变体 +│ │ ├── AudioToText.vue # 语音转文字 +│ │ └── QuestionExplanation.vue # 视频讲解 │ ├── components/ # 公共组件 │ ├── assets/ # 静态资源 │ └── MainLayout.vue # 布局组件 ├── vite.config.js # 开发代理配置(生产环境需在服务器复现) -├── package.json +├── package.json # 前端依赖配置 └── DEPLOY.md # 本文档 ``` + +--- + +## 十、后端服务详细说明 + +### 10.1 服务架构 + +后端服务基于 Express.js 构建,主要提供视频合成功能: + +- **技术栈**:Express.js + Fluent-FFmpeg +- **默认端口**:3001 +- **主要功能**:接收图片和音频 URL,合成 MP4 视频文件 + +### 10.2 API 接口 + +#### POST `/api/video/compose` + +合成视频接口,将多组图片和音频合成为视频。 + +**请求体示例**: +```json +{ + "slides": [ + { + "imageUrl": "https://example.com/image1.png", + "audioUrl": "https://example.com/audio1.mp3" + }, + { + "imageUrl": "https://example.com/image2.png", + "audioUrl": "https://example.com/audio2.mp3" + } + ], + "width": 1920, + "height": 1080 +} +``` + +**参数说明**: +- `slides`(必需):幻灯片数组,每个元素包含: + - `imageUrl`:图片 URL(支持 HTTP/HTTPS URL 或 base64 data URI) + - `audioUrl`:音频 URL(MP3 格式) +- `width`(可选):视频宽度,默认 1920 +- `height`(可选):视频高度,默认 1080 + +**响应**: +- Content-Type: `video/mp4` +- 返回合成后的 MP4 视频文件 + +#### GET `/api/video/health` + +健康检查接口,检查 FFmpeg 服务状态。 + +**响应示例**: +```json +{ + "status": "ok", + "message": "视频合成服务正常运行", + "formats": 300 +} +``` + +#### GET `/health` + +服务健康检查接口。 + +**响应示例**: +```json +{ + "status": "ok", + "timestamp": "2024-01-01T12:00:00.000Z" +} +``` + +### 10.3 环境变量配置 + +后端服务支持以下环境变量: + +| 环境变量 | 默认值 | 说明 | +|---------|--------|------| +| `PORT` | 3001 | 服务监听端口 | + +使用示例: +```bash +PORT=3002 pm2 start index.js --name ai-demo-server +``` + +### 10.4 临时文件管理 + +- 后端服务在 `server/temp/` 目录下存储临时文件 +- 每个视频合成任务会创建独立的子目录(使用 UUID 命名) +- 任务完成后,临时文件会自动清理 +- 如遇异常中断,可手动清理 `temp/` 目录 + +### 10.5 性能与资源要求 + +**建议配置**: +- **CPU**:2 核以上(视频合成需要较多 CPU 资源) +- **内存**:2GB 以上 +- **磁盘**:10GB 以上可用空间(临时文件存储) + +**并发处理**: +- 单个视频合成任务处理时间:约 10-60 秒(取决于片段数量和时长) +- 建议使用队列机制处理高并发请求(当前版本为同步处理) + +### 10.6 日志查看 + +使用 PM2 查看后端服务日志: +```bash +# 查看实时日志 +pm2 logs ai-demo-server + +# 查看最近 100 行日志 +pm2 logs ai-demo-server --lines 100 + +# 清空日志 +pm2 flush ai-demo-server +``` + +日志包含: +- 服务启动信息 +- FFmpeg 命令执行日志 +- 视频合成进度 +- 错误信息 + +### 10.7 监控与告警 + +建议监控以下指标: +- 服务进程状态(PM2 监控) +- 端口 3001 响应状态(健康检查) +- 磁盘空间(`temp/` 目录) +- CPU 和内存使用率 + +--- + +## 十一、Docker 部署(可选) + +### 11.1 后端服务 Dockerfile + +已提供 Dockerfile 位于 `Dockerfiles/backend.Dockerfile`(如需创建): + +```dockerfile +FROM node:20-alpine + +# 安装 FFmpeg +RUN apk add --no-cache ffmpeg + +WORKDIR /app + +# 复制依赖文件 +COPY server/package*.json ./ +RUN npm ci --only=production + +# 复制源码 +COPY server/ ./ + +# 创建临时目录 +RUN mkdir -p temp + +EXPOSE 3001 + +CMD ["node", "index.js"] +``` + +### 11.2 Docker Compose 部署 + +创建 `docker-compose.yml`: + +```yaml +version: '3.8' + +services: + backend: + build: + context: . + dockerfile: Dockerfiles/backend.Dockerfile + ports: + - "3001:3001" + volumes: + - ./server/temp:/app/temp + restart: unless-stopped + environment: + - PORT=3001 + + frontend: + image: nginx:alpine + ports: + - "80:80" + volumes: + - ./dist:/usr/share/nginx/html + - ./nginx.conf:/etc/nginx/conf.d/default.conf + depends_on: + - backend + restart: unless-stopped +``` + +启动: +```bash +docker-compose up -d +``` + +--- + +## 十二、安全建议 + +1. **HTTPS 强制**:生产环境务必启用 HTTPS +2. **API 密钥保护**:不要将 API 密钥提交到代码仓库 +3. **文件上传限制**:限制视频合成的图片和音频大小 +4. **频率限制**:对 `/api/video/compose` 接口添加速率限制 +5. **临时文件清理**:定期检查并清理异常终止的临时文件 +6. **日志审计**:记录所有视频合成请求的来源和处理结果 + +--- + +## 十三、更新与维护 + +### 更新前端 + +```bash +git pull +npm install +npm run build +# 重新部署 dist/ 目录 +``` + +### 更新后端 + +```bash +cd server +git pull +npm install +pm2 restart ai-demo-server +``` + +### 查看服务状态 + +```bash +pm2 status +pm2 logs +``` + +--- + +**文档版本**:v2.0 +**更新日期**:2024-01-01 +**更新内容**:新增后端视频合成服务部署说明