# 前端 Nginx - SAE 部署操作手册 **文档版本**: v1.0 **创建时间**: 2025-12-23 **适用范围**: AIclinicalresearch 平台前端服务 **部署目标**: 阿里云 SAE(Serverless 应用引擎) **镜像仓库**: 阿里云 ACR 个人版 --- ## 📋 目录 1. [前置条件检查](#1-前置条件检查) 2. [镜像信息确认](#2-镜像信息确认) 3. [创建SAE应用](#3-创建sae应用) 4. [配置环境变量](#4-配置环境变量) 5. [配置健康检查](#5-配置健康检查) 6. [配置公网访问](#6-配置公网访问) 7. [部署应用](#7-部署应用) 8. [验证部署](#8-验证部署) 9. [常见问题排查](#9-常见问题排查) 10. [日常运维](#10-日常运维) --- ## 1. 前置条件检查 ### ✅ **部署前必须完成的准备** | 检查项 | 状态 | 说明 | |--------|------|------| | **ACR镜像已推送** | ☑️ | 镜像地址:`crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0` | | **后端服务已部署** | ⬜ | 需要获取后端VPC内网地址(格式:`172.17.x.x:3001`) | | **VPC网络已创建** | ☑️ | VPC ID: `vpc-2ze055cptkew9c38w4r06` | | **交换机已创建** | ☑️ | 交换机 ID: `vsw-2zevacop039bxrmj6yc0c` (可用区F) | | **安全组已创建** | ☑️ | 安全组 ID: `sg-2zedk6fi8sgmmcwdu7tu` | ### 🔑 **必需的配置信息** 准备以下信息(在部署过程中需要): ```yaml # ACR 镜像信息 ACR域名(专有网络): crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com 命名空间: ai-clinical 镜像名称: ai-clinical_frontend-nginx 镜像版本: v1.0.0 # VPC网络信息 VPC ID: vpc-2ze055cptkew9c38w4r06 交换机ID: vsw-2zevacop039bxrmj6yc0c 安全组ID: sg-2zedk6fi8sgmmcwdu7tu # 后端服务信息(从后端SAE应用获取) 后端内网地址: 待获取(格式:172.17.x.x) 后端端口: 3001 ``` --- ## 2. 镜像信息确认 ### 📦 **ACR 镜像详情** ```yaml 服务类型: 个人版(免费) 命名空间: ai-clinical 仓库名称: ai-clinical_frontend-nginx 镜像完整地址(专有网络): crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0 镜像标签: - v1.0.0 (生产版本,digest: 68e97e28...) - latest (指向最新版本) 镜像大小: 91.9 MB 构建时间: 2025-12-23 ``` ### 🔍 **验证镜像存在** 登录ACR控制台验证:https://cr.console.aliyun.com/ 1. 进入【个人版】→【镜像仓库】 2. 找到 `ai-clinical_frontend-nginx` 3. 确认存在 `v1.0.0` 标签 --- ## 3. 创建SAE应用 ### 📍 **登录SAE控制台** 访问:https://sae.console.aliyun.com/ 选择地域:**华北2(北京)** ### 🆕 **创建新应用** 点击【创建应用】,按以下步骤填写: #### **步骤1:应用基本信息** ```yaml 应用名称: frontend-nginx-service 应用描述: AI临床研究平台 - 前端静态资源服务(React SPA + Nginx) 命名空间: 默认命名空间(或与后端同一命名空间) ``` #### **步骤2:应用部署方式** ```yaml 部署方式: 镜像 技术栈语言: 不限 ``` #### **步骤3:应用实例规格** ```yaml 实例规格: 0.5核 1GB 说明: - 前端Nginx占用资源极少 - 0.5核1GB完全够用 - 对比:后端需要2核4GB,Python需要2核4GB 实例数量: 2 说明: - 最小2个实例保证高可用 - 1个实例故障时,另1个继续服务 - 前端很少需要扩容 ``` **为什么前端只需要0.5核1GB?** | 服务类型 | 推荐规格 | 原因 | |---------|---------|------| | Node.js 后端 | 2核4GB | 处理AI对话、数据库查询、业务逻辑 | | Python 微服务 | 2核4GB | PDF提取是CPU密集型操作 | | **Nginx 前端** | **0.5核1GB** | **仅提供静态文件,消耗极少** | #### **步骤4:VPC网络配置** ```yaml VPC: vpc-2ze055cptkew9c38w4r06 (172.17.0.0/16) 交换机: vsw-2zevacop039bxrmj6yc0c 可用区: 华北2可用区F 网段: 172.17.0.0/24 安全组: sg-2zedk6fi8sgmmcwdu7tu ⚠️ 重要:必须与后端服务在同一VPC,否则无法通信 ``` #### **步骤5:镜像配置** ```yaml 镜像类型: 容器镜像服务个人版 镜像地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0 ⚠️ 注意事项: - 使用专有网络域名(带-vpc后缀),不使用公网域名 - 完整输入镜像地址(包括命名空间和标签) - 不要遗漏版本号 :v1.0.0 镜像版本: v1.0.0 镜像拉取策略: 总是拉取镜像(Always) 说明: - 每次部署都拉取最新镜像 - 确保使用最新代码 - 避免使用缓存的旧镜像 ``` #### **步骤6:应用容器配置** ```yaml 容器端口: 80 说明: - Nginx默认监听80端口 - 与Dockerfile中的EXPOSE 80一致 协议: TCP 启动命令: - 不填(使用Dockerfile中的ENTRYPOINT) 工作目录: - 不填(使用Dockerfile中的WORKDIR) ``` --- ## 4. 配置环境变量 ### ⚠️ **极其重要:后端服务地址配置** 环境变量配置错误是最常见的部署失败原因! ### 📍 **获取后端内网地址** **在配置前端之前,必须先获取后端的VPC内网地址:** 1. 登录 SAE 控制台 2. 进入应用列表 3. 找到 `nodejs-backend-service`(你的后端应用名称) 4. 点击进入应用详情 5. 查看【应用访问配置】→【VPC内网访问地址】 示例格式: ``` 172.17.0.15:3001 ``` 将IP地址和端口分别记录下来。 ### 🔧 **配置环境变量** 在SAE应用配置页面,找到【环境变量】配置项: ```yaml # 必需配置(必填) BACKEND_SERVICE_HOST: 172.17.0.15 说明: - 这是后端服务的VPC内网IP地址(从上一步获取) - 不要加http://前缀 - 不要包含端口号 - 如果不配置,容器启动会失败并报错 # 可选配置(有默认值) BACKEND_SERVICE_PORT: 3001 说明: - 后端服务的端口号 - 默认值是3001 - 如果你的后端使用其他端口,需要修改 ``` ### ❌ **常见错误** | 错误配置 | 正确配置 | 说明 | |---------|---------|------| | `http://172.17.0.15` | `172.17.0.15` | 不要加协议前缀 | | `172.17.0.15:3001` | `172.17.0.15` | 不要包含端口(端口单独配置) | | `backend-service` | `172.17.0.15` | 必须使用IP,不要用主机名 | | `localhost` | `172.17.0.15` | 不能用localhost | | 不配置 | `172.17.0.15` | 必须配置,否则启动失败 | ### ✅ **配置验证** 配置完成后,点击【验证】,确保: - ✅ 变量名称拼写正确(区分大小写) - ✅ 变量值格式正确(纯IP地址) - ✅ 没有多余的空格 --- ## 5. 配置健康检查 ### 🏥 **健康检查配置** ```yaml 检查方式: HTTP 请求 检查路径: /health 说明: - Nginx配置中专门提供的健康检查端点 - 返回纯文本 "healthy" - 不依赖后端服务 检查端口: 80 说明:与容器端口一致 检查协议: HTTP 说明:不是HTTPS 超时时间: 3秒 说明:静态端点,3秒足够 检查间隔: 10秒 说明:每10秒检查一次 不健康阈值: 3次 说明:连续失败3次后标记为不健康 健康阈值: 2次 说明:连续成功2次后标记为健康 初始延迟: 30秒 说明: - Nginx启动很快(5-10秒) - 30秒足够镜像拉取和容器启动 ``` ### 🔍 **健康检查原理** ``` SAE健康检查器 ↓ (每10秒) curl http://容器IP:80/health ↓ Nginx处理 /health 请求 ↓ 返回: HTTP 200 + "healthy" ↓ SAE标记实例为健康 ✅ ``` **如果健康检查失败,SAE会:** 1. 标记实例为不健康 2. 停止向该实例转发流量 3. 连续失败3次后,重启容器 --- ## 6. 配置公网访问 ### 🌐 **访问方式选择** #### **方案A:使用SAE提供的公网地址(推荐用于测试)** ```yaml 配置方式: 1. 在应用配置页面找到【应用访问配置】 2. 开启【公网访问】 3. SAE自动分配域名 获得的访问地址: 格式: frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com 协议: HTTPS(SAE自动配置证书) 优点: - ✅ 免费 - ✅ 自动HTTPS - ✅ 立即可用 缺点: - ❌ 域名难记 - ❌ 无法自定义域名 - ❌ 证书是SAE的,不是你的域名 ``` #### **方案B:绑定自定义域名(推荐用于生产)** ```yaml 前置条件: - 已有自己的域名(如 app.yizheng.ai) - 域名已备案(如果服务器在中国大陆) - 有SSL证书(可以使用免费的Let's Encrypt) 配置步骤: 1. 在域名服务商添加CNAME解析 app.yizheng.ai → frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com 2. 在SAE控制台绑定域名 【应用访问配置】→【自定义域名】→【添加域名】 3. 上传SSL证书 【应用访问配置】→【HTTPS设置】→【上传证书】 4. 启用强制HTTPS 开启【强制HTTPS跳转】 获得的访问地址: https://app.yizheng.ai 优点: - ✅ 品牌域名 - ✅ 用户信任度高 - ✅ SEO友好 缺点: - ⚠️ 需要域名和证书 - ⚠️ 需要ICP备案(如果在中国) ``` ### 🔒 **HTTPS配置(生产环境必须)** 如果使用方案B(自定义域名),强烈建议配置HTTPS: ```yaml 证书来源选择: 方案1: 使用免费的Let's Encrypt证书 - 阿里云SSL证书服务可以申请免费证书 - 有效期3个月,需要定期更新 方案2: 购买商业证书 - 有效期1年 - 品牌信任度更高 - 支持更多特性 证书配置: 1. 准备证书文件 - 证书文件:domain.crt 或 domain.pem - 私钥文件:domain.key 2. 在SAE上传证书 【应用访问配置】→【HTTPS设置】→【上传证书】 3. 启用强制HTTPS 开启【HTTP自动跳转HTTPS】 ``` --- ## 7. 部署应用 ### 🚀 **执行部署** 确认所有配置无误后: 1. 回到应用配置页面顶部 2. 点击【部署】按钮 3. 确认部署信息 4. 点击【确定】 ### ⏱️ **部署过程(约2-3分钟)** ``` 1. 镜像拉取阶段 (30-60秒) ├─ SAE连接到ACR ├─ 验证镜像存在 ├─ 下载镜像层(91.9MB) └─ 解压镜像 2. 容器启动阶段 (10-20秒) ├─ 创建容器 ├─ 注入环境变量 ├─ 执行docker-entrypoint.sh ├─ envsubst替换nginx.conf ├─ 验证Nginx配置 └─ 启动Nginx进程 3. 健康检查阶段 (30-60秒) ├─ 等待30秒(初始延迟) ├─ 第1次检查 /health ├─ 第2次检查 /health(10秒后) └─ 标记为健康 ✅ 4. 流量切换阶段 (5-10秒) ├─ 将新实例加入负载均衡 ├─ 从负载均衡移除旧实例 └─ 部署完成 ✅ ``` ### 📊 **部署状态监控** 部署过程中可以实时查看: ```yaml 查看方式: 【应用详情】→【实例列表】→【查看实例状态】 状态说明: - 创建中: 正在拉取镜像 - 启动中: 正在启动容器 - 运行中: 容器已启动,等待健康检查 - 健康: 健康检查通过,可以接收流量 ✅ - 不健康: 健康检查失败 ❌ - 停止: 实例已停止 ``` ### ❌ **部署失败常见原因** | 失败阶段 | 错误信息 | 解决方法 | |---------|---------|---------| | 镜像拉取 | `image not found` | 检查镜像地址是否正确,确认使用-vpc域名 | | 镜像拉取 | `unauthorized` | 检查ACR访问权限,确认SAE有拉取权限 | | 容器启动 | `BACKEND_SERVICE_HOST required` | 检查环境变量是否配置 | | 健康检查 | `connection refused` | 检查容器端口配置(应该是80) | | 健康检查 | `404 not found` | 检查健康检查路径(应该是/health) | --- ## 8. 验证部署 ### ✅ **验证清单** 部署成功后,按以下步骤验证: #### **步骤1:查看实例状态** ```bash 位置: 【应用详情】→【实例列表】 检查项: ☑️ 实例数量: 2个实例 ☑️ 实例状态: 全部显示"健康" ☑️ 健康检查: 全部通过 ``` #### **步骤2:查看启动日志** ```bash 位置: 【应用详情】→【日志】→【实时日志】 应该看到: ============================================ Starting Frontend Nginx Service Backend Service: 172.17.0.15:3001 Container Timezone: Asia/Shanghai Current Time: Tue Dec 23 21:07:35 CST 2025 ============================================ nginx: configuration file /etc/nginx/nginx.conf test is successful ✅ 如果看到以上日志,说明配置正确 ❌ 如果看到 "BACKEND_SERVICE_HOST required",说明环境变量未配置 ``` #### **步骤3:测试健康检查端点** ```bash # 获取公网访问地址 公网地址: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com # 测试健康检查(使用浏览器或curl) 访问: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com/health 预期返回: Status: 200 OK Content: healthy ✅ 如果返回 "healthy",说明前端服务正常 ``` #### **步骤4:测试主页访问** ```bash # 访问主页 访问: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com/ 检查项: ☑️ 页面能正常加载(不是空白页) ☑️ 看到React应用界面 ☑️ CSS样式正确显示 ☑️ JavaScript正常执行 ``` #### **步骤5:测试SPA路由** ```bash # 访问一个不存在的路径(测试React Router) 访问: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com/dashboard 预期行为: ✅ 不报404错误 ✅ 返回index.html ✅ React Router接管路由 ✅ 显示对应的页面组件 ❌ 如果看到Nginx 404页面,说明nginx.conf配置有问题 ``` #### **步骤6:测试API代理(关键)** ```bash # 打开浏览器开发者工具(F12)→ Console标签 # 执行以下代码测试API代理 fetch('/api/v1/health') .then(res => res.json()) .then(data => console.log(data)) 预期结果: ✅ 请求成功(Status 200) ✅ 返回后端的响应数据 ✅ 没有CORS错误 ❌ 如果看到CORS错误,说明反向代理配置有问题 ❌ 如果看到连接失败,说明后端地址配置错误 ``` #### **步骤7:测试静态资源缓存** ```bash # 在浏览器开发者工具 → Network标签 # 第一次访问 ✅ index.html: 状态200,Cache-Control: no-cache ✅ index-xxxxx.js: 状态200,Cache-Control: 1年 # 刷新页面(第二次访问) ✅ index.html: 状态200(每次都重新获取) ✅ index-xxxxx.js: 状态200 (from disk cache)(使用缓存) ``` #### **步骤8:测试Gzip压缩** ```bash # 在浏览器开发者工具 → Network标签 # 点击任意JS文件 检查Response Headers: ✅ Content-Encoding: gzip ✅ 文件大小减少60-70% 示例: 原始大小: 1.2 MB 传输大小: 350 KB (gzip压缩后) ``` ### 🎉 **部署成功标志** 如果以上8个步骤全部通过,恭喜!前端服务部署成功! --- ## 9. 常见问题排查 ### ❌ **问题1:实例健康检查失败** **症状:** ``` 实例状态显示"不健康" 健康检查失败 ``` **排查步骤:** ```bash 1. 查看实例日志 【应用详情】→【日志】→【实时日志】→【选择实例】 如果看到: - "BACKEND_SERVICE_HOST required" → 环境变量未配置 - "nginx: configuration file test failed" → nginx.conf语法错误 - 没有日志 → 容器没有启动 2. 检查健康检查配置 【应用配置】→【健康检查】 确认: - 检查路径: /health(不是 /) - 检查端口: 80(不是3000或其他) - 检查协议: HTTP(不是HTTPS) 3. 手动测试健康检查 在SAE Webshell中执行: curl http://localhost/health 预期返回: healthy ``` **解决方法:** - 配置缺失的环境变量 - 修正健康检查路径 - 检查容器端口配置 --- ### ❌ **问题2:页面能访问,但API请求失败** **症状:** ``` 前端页面正常显示 调用API时报错: Network Error 或 504 Gateway Timeout ``` **排查步骤:** ```bash 1. 检查浏览器Console 看到的错误: - "ERR_CONNECTION_REFUSED" → 后端服务未启动 - "504 Gateway Timeout" → 后端响应超时 - "502 Bad Gateway" → 后端地址错误 2. 检查环境变量配置 【应用配置】→【环境变量】 验证: - BACKEND_SERVICE_HOST 是否配置 - IP地址是否正确(从后端SAE应用获取) - 不要有http://前缀 - 不要包含端口号 3. 测试后端服务可达性 在前端容器的Webshell中: curl http://172.17.0.15:3001/api/v1/health 如果失败: - 检查后端服务是否运行 - 检查VPC网络是否相同 - 检查安全组规则 4. 查看Nginx错误日志 docker logs 2>&1 | grep error 常见错误: - "upstream: "http://172.17.0.15:3001/..." → 后端地址正确 - "connect() failed" → 后端不可达 ``` **解决方法:** - 修正环境变量BACKEND_SERVICE_HOST - 确保前后端在同一VPC - 检查安全组规则允许VPC内网访问 - 重启前端应用使配置生效 --- ### ❌ **问题3:刷新页面报404** **症状:** ``` 访问主页正常 点击链接跳转正常 刷新页面(F5)→ 404 Not Found ``` **原因:** React Router使用浏览器路由(BrowserRouter),刷新时Nginx需要将所有路由回退到index.html。 **排查步骤:** ```bash 1. 访问一个React路由 例如: https://your-domain.com/dashboard 2. 按F5刷新页面 ❌ 错误现象: 看到Nginx 404页面 ✅ 正确现象: 页面正常显示 3. 检查nginx.conf配置 登录容器Webshell: cat /etc/nginx/nginx.conf | grep "try_files" 应该看到: try_files $uri $uri/ /index.html; ``` **解决方法:** 如果nginx.conf中没有`try_files`配置,需要重新构建镜像: ```nginx # 在nginx.conf中确保有以下配置 location / { try_files $uri $uri/ /index.html; } ``` --- ### ❌ **问题4:静态资源404** **症状:** ``` HTML能加载 JS/CSS文件404 Not Found 页面显示为纯文本(无样式) ``` **排查步骤:** ```bash 1. 检查浏览器Network标签 看到: GET https://your-domain.com/assets/index-xxxxx.js 404 2. 检查index.html中的资源路径 curl https://your-domain.com/ | grep assets 正确示例: 错误示例: # 相对路径 # 错误base 3. 检查Vite配置 查看frontend-v2/vite.config.ts: 正确配置: export default defineConfig({ base: '/', // ✅ 默认值 }) 错误配置: export default defineConfig({ base: '/app/', // ❌ 除非确实需要 }) ``` **解决方法:** 1. 修改 `vite.config.ts`,确保 `base: '/'` 2. 重新构建前端:`npm run build` 3. 重新构建Docker镜像 4. 推送到ACR 5. SAE重新部署 --- ### ❌ **问题5:环境变量未生效** **症状:** ``` 配置了环境变量 但容器启动日志显示变量为空 ``` **排查步骤:** ```bash 1. 查看容器启动日志 【应用详情】→【日志】→【实时日志】 看到: Backend Service: ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT} ❌ 这说明envsubst没有替换变量 2. 进入容器Webshell检查 echo $BACKEND_SERVICE_HOST 如果为空 → SAE环境变量未传入 如果有值 → envsubst执行失败 3. 检查docker-entrypoint.sh cat /docker-entrypoint.sh 确认有: envsubst '${BACKEND_SERVICE_HOST} ${BACKEND_SERVICE_PORT}' \ < /etc/nginx/templates/nginx.conf.template \ > /etc/nginx/nginx.conf ``` **解决方法:** 1. 在SAE控制台重新配置环境变量 2. 确保变量名拼写正确(区分大小写) 3. 重启应用使配置生效 --- ## 10. 日常运维 ### 📊 **监控指标** #### **实时监控** ```yaml 查看位置: 【应用详情】→【监控】 关键指标: CPU使用率: 健康范围: < 30% 告警阈值: > 60% 说明: Nginx极少超过30% 内存使用率: 健康范围: < 50% 告警阈值: > 80% 说明: Nginx内存占用很低 请求QPS: 观察访问量趋势 平均响应时间: 健康范围: < 50ms 告警阈值: > 200ms 说明: 静态文件响应极快 错误率: 健康范围: < 0.1% 告警阈值: > 1% ``` #### **日志查看** ```yaml 实时日志: 位置: 【应用详情】→【日志】→【实时日志】 正常日志示例: 172.17.0.10 - - [23/Dec/2025:10:30:00 +0800] "GET / HTTP/1.1" 200 1234 172.17.0.10 - - [23/Dec/2025:10:30:01 +0800] "GET /assets/index.js HTTP/1.1" 200 567890 API代理日志: 172.17.0.10 - - [23/Dec/2025:10:30:02 +0800] "GET /api/v1/projects HTTP/1.1" 200 8765 错误日志: 2025/12/23 10:30:04 [error] connect() failed (111: Connection refused) → 后端服务连接失败 历史日志: 位置: 【应用详情】→【日志】→【历史日志】 保留时间: 7天 ``` --- ### 🔄 **版本更新流程** 当前端代码有更新时,按以下流程部署新版本: #### **步骤1:本地构建新版本** ```bash # 在frontend-v2目录 cd AIclinicalresearch/frontend-v2 # 测试构建 npm run build # 构建Docker镜像(版本号+1) docker build -t frontend-service:v1.0.1 . # 验证镜像大小 docker images frontend-service:v1.0.1 ``` #### **步骤2:推送到ACR** ```bash # 登录ACR echo fengzhibo117 | docker login --username=gofeng117@163.com --password-stdin crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com # 打标签 docker tag frontend-service:v1.0.1 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.1 docker tag frontend-service:v1.0.1 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:latest # 推送镜像 docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.1 docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:latest ``` #### **步骤3:SAE灰度发布(推荐)** ```yaml 目的: 降低更新风险,先更新部分实例验证 操作步骤: 1. 登录SAE控制台 → 进入应用详情 2. 点击【部署】→【灰度发布】 3. 配置灰度策略: 灰度实例数: 1 灰度时长: 5分钟 镜像版本: v1.0.1 4. 点击【确定】 5. 观察灰度实例: - 查看实例状态(健康) - 查看错误日志(无错误) - 访问测试(功能正常) 6. 确认无问题后,点击【全量发布】 7. 如果发现问题,点击【回滚】 - 自动回滚到上一个版本 - 无需手动操作 ``` #### **步骤4:全量发布** 如果不使用灰度发布,直接全量更新: ```yaml 操作步骤: 1. 登录SAE控制台 → 进入应用详情 2. 点击【部署】 3. 修改镜像版本: 从: v1.0.0 到: v1.0.1 4. 点击【确定】 5. 等待部署完成(2-3分钟) 6. 验证新版本: - 查看实例状态 - 访问前端页面 - 测试核心功能 ``` --- ### 🔙 **回滚操作** 如果新版本出现问题,可以快速回滚: ```yaml 操作步骤: 1. 登录SAE控制台 → 进入应用详情 2. 点击【变更记录】 3. 找到上一个稳定版本(如v1.0.0) 4. 点击【回滚】 5. 确认回滚 6. 等待回滚完成(1-2分钟) 回滚时间: - 镜像已缓存: 1-2分钟 - 镜像未缓存: 2-3分钟 ``` --- ### 🗑️ **清理旧版本镜像** 定期清理ACR中的旧版本镜像,节省存储空间: ```yaml 清理策略: - 保留最近3个版本 - 删除30天前的旧版本 - 保留带有特殊标签的版本(如stable、prod) 操作步骤: 1. 登录ACR控制台 2. 进入镜像仓库 → ai-clinical_frontend-nginx 3. 查看所有版本 4. 选择要删除的版本(勾选) 5. 点击【删除】 6. 确认删除 ⚠️ 注意: - 不要删除正在使用的版本 - 删除前确认SAE应用已更新到新版本 - 建议至少保留2个版本以便回滚 ``` --- ### 📈 **弹性伸缩配置** 前端Nginx服务通常不需要频繁扩缩容,但可以配置自动伸缩: ```yaml 配置位置: 【应用配置】→【弹性伸缩】 最小实例数: 2 说明: 保证高可用,至少2个实例 最大实例数: 5 说明: 前端流量波动通常不大,5个实例足够 扩容策略: 指标: CPU使用率 阈值: > 60% 持续 3分钟 每次扩容: +1个实例 冷却时间: 3分钟 说明: Nginx很少达到60% CPU 缩容策略: 指标: CPU使用率 阈值: < 20% 持续 5分钟 每次缩容: -1个实例 冷却时间: 5分钟 最小保留: 2个实例 ⚠️ 实际情况: 前端Nginx性能极高,2个0.5核实例可以支撑: - 1000+ QPS(静态文件) - 100+ QPS(API代理) - 几乎不需要扩容 ``` --- ### 🚨 **告警配置** 配置关键指标告警,及时发现问题: ```yaml 配置位置: 【云监控】→【应用监控】→【创建告警规则】 推荐告警规则: 1. 实例健康检查失败 - 条件: 健康检查失败 > 3次 - 级别: 紧急 - 通知: 短信 + 钉钉 2. CPU使用率过高 - 条件: CPU > 60% 持续 5分钟 - 级别: 警告 - 通知: 钉钉 + 邮件 3. 内存使用率过高 - 条件: 内存 > 80% 持续 5分钟 - 级别: 警告 - 通知: 钉钉 + 邮件 4. 错误率过高 - 条件: 错误率 > 1% 持续 3分钟 - 级别: 紧急 - 通知: 短信 + 钉钉 5. 平均响应时间过长 - 条件: 响应时间 > 500ms 持续 5分钟 - 级别: 警告 - 通知: 钉钉 + 邮件 通知方式配置: - 钉钉机器人: 创建群聊机器人,获取Webhook - 邮件: 配置告警联系人邮箱 - 短信: 配置手机号(建议仅用于紧急告警) ``` --- ## 📚 附录 ### 📝 **配置文件清单** 部署过程中涉及的配置文件: ```yaml 本地文件 (AIclinicalresearch/frontend-v2/): - Dockerfile (多阶段构建配置) - nginx.conf (Nginx服务器配置) - docker-entrypoint.sh (容器启动脚本) - .dockerignore (构建排除文件) SAE配置 (在控制台配置): - 应用基本信息 - 实例规格和数量 - VPC网络配置 - 镜像地址和版本 - 环境变量 - 健康检查 - 公网访问配置 ``` --- ### 🔗 **相关文档链接** ```yaml 阿里云官方文档: - SAE产品文档: https://help.aliyun.com/product/1172298.html - ACR产品文档: https://help.aliyun.com/product/60716.html - VPC产品文档: https://help.aliyun.com/product/27706.html 项目内部文档: - 前端Nginx部署指南: docs/05-部署文档/06-前端Nginx-SAE容器部署指南.md - 快速部署SOP: docs/05-部署文档/01-快速部署SOP-零基础版.md - 部署架构总览: docs/05-部署文档/00-部署架构总览.md ``` --- ### 💡 **最佳实践总结** ```yaml 安全性: ✅ 使用专有网络(VPC)隔离 ✅ 环境变量存储敏感信息 ✅ 启用HTTPS(生产环境) ✅ 配置安全组规则 ✅ 隐藏Nginx版本号 性能: ✅ 启用Gzip压缩(减少70%传输) ✅ 配置合理的缓存策略 ✅ 使用CDN加速(可选) ✅ 优化Docker镜像大小 可靠性: ✅ 至少2个实例(高可用) ✅ 配置健康检查 ✅ 启用自动伸缩 ✅ 配置告警监控 ✅ 灰度发布降低风险 可维护性: ✅ 使用语义化版本号 ✅ 保留最近3个版本以便回滚 ✅ 定期清理旧版本镜像 ✅ 记录变更日志 ✅ 文档及时更新 ``` --- ### ❓ **常见问题FAQ** **Q1: 前端服务需要多大的规格?** ``` A: 0.5核1GB足够。 - Nginx极其高效,占用资源很少 - 0.5核可以支撑1000+ QPS - 不要过度配置浪费资源 ``` **Q2: 需要配置多少个实例?** ``` A: 生产环境建议2个实例。 - 保证高可用(1个故障时另1个继续服务) - 前端很少需要3个以上实例 - 流量特别大时可以配置CDN ``` **Q3: 如何知道后端服务的内网地址?** ``` A: 从后端SAE应用获取: 1. 登录SAE控制台 2. 进入后端应用详情 3. 查看【应用访问配置】→【VPC内网访问地址】 4. 复制IP地址(格式:172.17.x.x) ``` **Q4: 环境变量配置后没生效怎么办?** ``` A: 需要重启应用: 1. 修改环境变量 2. 点击【重启】或【重新部署】 3. 等待实例重启完成 4. 查看启动日志确认变量值 ``` **Q5: 部署新版本后如何快速回滚?** ``` A: SAE支持一键回滚: 1. 进入【变更记录】 2. 找到上一个稳定版本 3. 点击【回滚】 4. 等待1-2分钟完成回滚 ``` **Q6: 如何配置HTTPS?** ``` A: 两种方式: 1. 使用SAE提供的域名(自动HTTPS) 2. 绑定自定义域名并上传SSL证书 生产环境强烈建议使用HTTPS ``` **Q7: 前端需要连接数据库吗?** ``` A: 不需要。 - 前端是纯静态资源(HTML/JS/CSS) - 只需要通过Nginx代理访问后端API - 数据库连接由后端服务处理 ``` **Q8: 每次更新都要重新构建Docker镜像吗?** ``` A: 是的。 1. 修改前端代码 2. npm run build(生成新的dist/) 3. docker build(打包到镜像) 4. docker push(推送到ACR) 5. SAE重新部署(拉取新镜像) 这是标准的容器化部署流程 ``` **Q9: Docker镜像太大怎么办?** ``` A: 当前镜像只有92MB,已经很小了。 - 多阶段构建(只保留运行时文件) - Alpine基础镜像(最小Linux发行版) - 已经是最优化的状态 ``` **Q10: 如何查看实时访问日志?** ``` A: SAE控制台查看: 【应用详情】→【日志】→【实时日志】 可以看到: - 所有HTTP请求(URL、状态码、响应时间) - Nginx错误日志 - 容器启动日志 ``` --- ## 🎯 **部署检查清单** 最后,用这个清单确认部署完成: ```yaml 部署前准备: ☑️ ACR镜像已推送(v1.0.0) ☑️ 后端服务已部署(获取内网地址) ☑️ VPC和交换机已创建 ☑️ 安全组已配置 SAE应用配置: ☑️ 应用名称:frontend-nginx-service ☑️ 实例规格:0.5核1GB ☑️ 实例数量:2 ☑️ 镜像地址:专有网络域名(带-vpc) ☑️ 镜像版本:v1.0.0 环境变量配置: ☑️ BACKEND_SERVICE_HOST:已配置(172.17.x.x) ☑️ BACKEND_SERVICE_PORT:已配置(3001) 健康检查配置: ☑️ 检查路径:/health ☑️ 检查端口:80 ☑️ 检查协议:HTTP 部署验证: ☑️ 实例状态:健康 ☑️ 健康检查:通过 ☑️ 主页访问:正常 ☑️ SPA路由:正常(刷新不404) ☑️ API代理:正常(无CORS错误) ☑️ 静态资源:正常(缓存生效) ☑️ Gzip压缩:已启用 监控和告警: ☑️ 实时监控:已配置 ☑️ 日志查看:可访问 ☑️ 告警规则:已配置 全部完成,部署成功!🎉 ``` --- **文档结束** 如有疑问,请查阅相关文档或联系技术支持。 祝部署顺利!🚀