Features: - PatientWechatCallbackController for URL verification and message handling - PatientWechatService for template and customer messages - Support for secure mode (message encryption/decryption) - Simplified route /wechat/patient/callback for WeChat config - Event handlers for subscribe/unsubscribe/text messages - Template message for visit reminders Technical details: - Reuse @wecom/crypto for encryption (compatible with Official Account) - Relaxed Fastify schema validation to prevent early request blocking - Access token caching (7000s with 5min pre-refresh) - Comprehensive logging for debugging Testing: Local URL verification passed, ready for SAE deployment Status: Code complete, waiting for WeChat platform configuration
31 KiB
前端 Nginx - SAE 部署操作手册
文档版本: v1.0
创建时间: 2025-12-23
适用范围: AIclinicalresearch 平台前端服务
部署目标: 阿里云 SAE(Serverless 应用引擎)
镜像仓库: 阿里云 ACR 个人版
📋 目录
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 |
🔑 必需的配置信息
准备以下信息(在部署过程中需要):
# 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 镜像详情
服务类型: 个人版(免费)
命名空间: 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/
- 进入【个人版】→【镜像仓库】
- 找到
ai-clinical_frontend-nginx - 确认存在
v1.0.0标签
3. 创建SAE应用
📍 登录SAE控制台
访问:https://sae.console.aliyun.com/
选择地域:华北2(北京)
🆕 创建新应用
点击【创建应用】,按以下步骤填写:
步骤1:应用基本信息
应用名称: frontend-nginx-service
应用描述: AI临床研究平台 - 前端静态资源服务(React SPA + Nginx)
命名空间: 默认命名空间(或与后端同一命名空间)
步骤2:应用部署方式
部署方式: 镜像
技术栈语言: 不限
步骤3:应用实例规格
实例规格: 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网络配置
VPC: vpc-2ze055cptkew9c38w4r06 (172.17.0.0/16)
交换机: vsw-2zevacop039bxrmj6yc0c
可用区: 华北2可用区F
网段: 172.17.0.0/24
安全组: sg-2zedk6fi8sgmmcwdu7tu
⚠️ 重要:必须与后端服务在同一VPC,否则无法通信
步骤5:镜像配置
镜像类型: 容器镜像服务个人版
镜像地址: 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:应用容器配置
容器端口: 80
说明:
- Nginx默认监听80端口
- 与Dockerfile中的EXPOSE 80一致
协议: TCP
启动命令:
- 不填(使用Dockerfile中的ENTRYPOINT)
工作目录:
- 不填(使用Dockerfile中的WORKDIR)
4. 配置环境变量
⚠️ 极其重要:后端服务地址配置
环境变量配置错误是最常见的部署失败原因!
📍 获取后端内网地址
在配置前端之前,必须先获取后端的VPC内网地址:
- 登录 SAE 控制台
- 进入应用列表
- 找到
nodejs-backend-service(你的后端应用名称) - 点击进入应用详情
- 查看【应用访问配置】→【VPC内网访问地址】
示例格式:
172.17.0.15:3001
将IP地址和端口分别记录下来。
🔧 配置环境变量
在SAE应用配置页面,找到【环境变量】配置项:
# 必需配置(必填)
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. 配置健康检查
🏥 健康检查配置
检查方式: 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会:
- 标记实例为不健康
- 停止向该实例转发流量
- 连续失败3次后,重启容器
6. 配置公网访问
🌐 访问方式选择
方案A:使用SAE提供的公网地址(推荐用于测试)
配置方式:
1. 在应用配置页面找到【应用访问配置】
2. 开启【公网访问】
3. SAE自动分配域名
获得的访问地址:
格式: frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com
协议: HTTPS(SAE自动配置证书)
优点:
- ✅ 免费
- ✅ 自动HTTPS
- ✅ 立即可用
缺点:
- ❌ 域名难记
- ❌ 无法自定义域名
- ❌ 证书是SAE的,不是你的域名
方案B:绑定自定义域名(推荐用于生产)
前置条件:
- 已有自己的域名(如 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:
证书来源选择:
方案1: 使用免费的Let's Encrypt证书
- 阿里云SSL证书服务可以申请免费证书
- 有效期3个月,需要定期更新
方案2: 购买商业证书
- 有效期1年
- 品牌信任度更高
- 支持更多特性
证书配置:
1. 准备证书文件
- 证书文件:domain.crt 或 domain.pem
- 私钥文件:domain.key
2. 在SAE上传证书
【应用访问配置】→【HTTPS设置】→【上传证书】
3. 启用强制HTTPS
开启【HTTP自动跳转HTTPS】
7. 部署应用
🚀 执行部署
确认所有配置无误后:
- 回到应用配置页面顶部
- 点击【部署】按钮
- 确认部署信息
- 点击【确定】
⏱️ 部署过程(约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秒)
├─ 将新实例加入负载均衡
├─ 从负载均衡移除旧实例
└─ 部署完成 ✅
📊 部署状态监控
部署过程中可以实时查看:
查看方式:
【应用详情】→【实例列表】→【查看实例状态】
状态说明:
- 创建中: 正在拉取镜像
- 启动中: 正在启动容器
- 运行中: 容器已启动,等待健康检查
- 健康: 健康检查通过,可以接收流量 ✅
- 不健康: 健康检查失败 ❌
- 停止: 实例已停止
❌ 部署失败常见原因
| 失败阶段 | 错误信息 | 解决方法 |
|---|---|---|
| 镜像拉取 | image not found |
检查镜像地址是否正确,确认使用-vpc域名 |
| 镜像拉取 | unauthorized |
检查ACR访问权限,确认SAE有拉取权限 |
| 容器启动 | BACKEND_SERVICE_HOST required |
检查环境变量是否配置 |
| 健康检查 | connection refused |
检查容器端口配置(应该是80) |
| 健康检查 | 404 not found |
检查健康检查路径(应该是/health) |
8. 验证部署
✅ 验证清单
部署成功后,按以下步骤验证:
步骤1:查看实例状态
位置: 【应用详情】→【实例列表】
检查项:
☑️ 实例数量: 2个实例
☑️ 实例状态: 全部显示"健康"
☑️ 健康检查: 全部通过
步骤2:查看启动日志
位置: 【应用详情】→【日志】→【实时日志】
应该看到:
============================================
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:测试健康检查端点
# 获取公网访问地址
公网地址: 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:测试主页访问
# 访问主页
访问: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com/
检查项:
☑️ 页面能正常加载(不是空白页)
☑️ 看到React应用界面
☑️ CSS样式正确显示
☑️ JavaScript正常执行
步骤5:测试SPA路由
# 访问一个不存在的路径(测试React Router)
访问: https://frontend-nginx-service-xxxxx.cn-beijing.sae.aliyuncs.com/dashboard
预期行为:
✅ 不报404错误
✅ 返回index.html
✅ React Router接管路由
✅ 显示对应的页面组件
❌ 如果看到Nginx 404页面,说明nginx.conf配置有问题
步骤6:测试API代理(关键)
# 打开浏览器开发者工具(F12)→ Console标签
# 执行以下代码测试API代理
fetch('/api/v1/health')
.then(res => res.json())
.then(data => console.log(data))
预期结果:
✅ 请求成功(Status 200)
✅ 返回后端的响应数据
✅ 没有CORS错误
❌ 如果看到CORS错误,说明反向代理配置有问题
❌ 如果看到连接失败,说明后端地址配置错误
步骤7:测试静态资源缓存
# 在浏览器开发者工具 → 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压缩
# 在浏览器开发者工具 → Network标签
# 点击任意JS文件
检查Response Headers:
✅ Content-Encoding: gzip
✅ 文件大小减少60-70%
示例:
原始大小: 1.2 MB
传输大小: 350 KB (gzip压缩后)
🎉 部署成功标志
如果以上8个步骤全部通过,恭喜!前端服务部署成功!
9. 常见问题排查
❌ 问题1:实例健康检查失败
症状:
实例状态显示"不健康"
健康检查失败
排查步骤:
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
排查步骤:
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 <container_id> 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。
排查步骤:
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.conf中确保有以下配置
location / {
try_files $uri $uri/ /index.html;
}
❌ 问题4:静态资源404
症状:
HTML能加载
JS/CSS文件404 Not Found
页面显示为纯文本(无样式)
排查步骤:
1. 检查浏览器Network标签
看到:
GET https://your-domain.com/assets/index-xxxxx.js 404
2. 检查index.html中的资源路径
curl https://your-domain.com/ | grep assets
正确示例:
<script src="/assets/index-xxxxx.js"></script>
错误示例:
<script src="./assets/index-xxxxx.js"></script> # 相对路径
<script src="/app/assets/index-xxxxx.js"></script> # 错误base
3. 检查Vite配置
查看frontend-v2/vite.config.ts:
正确配置:
export default defineConfig({
base: '/', // ✅ 默认值
})
错误配置:
export default defineConfig({
base: '/app/', // ❌ 除非确实需要
})
解决方法:
- 修改
vite.config.ts,确保base: '/' - 重新构建前端:
npm run build - 重新构建Docker镜像
- 推送到ACR
- SAE重新部署
❌ 问题5:环境变量未生效
症状:
配置了环境变量
但容器启动日志显示变量为空
排查步骤:
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
解决方法:
- 在SAE控制台重新配置环境变量
- 确保变量名拼写正确(区分大小写)
- 重启应用使配置生效
10. 日常运维
📊 监控指标
实时监控
查看位置: 【应用详情】→【监控】
关键指标:
CPU使用率:
健康范围: < 30%
告警阈值: > 60%
说明: Nginx极少超过30%
内存使用率:
健康范围: < 50%
告警阈值: > 80%
说明: Nginx内存占用很低
请求QPS:
观察访问量趋势
平均响应时间:
健康范围: < 50ms
告警阈值: > 200ms
说明: 静态文件响应极快
错误率:
健康范围: < 0.1%
告警阈值: > 1%
日志查看
实时日志:
位置: 【应用详情】→【日志】→【实时日志】
正常日志示例:
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:本地构建新版本
# 在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
# 登录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灰度发布(推荐)
目的: 降低更新风险,先更新部分实例验证
操作步骤:
1. 登录SAE控制台 → 进入应用详情
2. 点击【部署】→【灰度发布】
3. 配置灰度策略:
灰度实例数: 1
灰度时长: 5分钟
镜像版本: v1.0.1
4. 点击【确定】
5. 观察灰度实例:
- 查看实例状态(健康)
- 查看错误日志(无错误)
- 访问测试(功能正常)
6. 确认无问题后,点击【全量发布】
7. 如果发现问题,点击【回滚】
- 自动回滚到上一个版本
- 无需手动操作
步骤4:全量发布
如果不使用灰度发布,直接全量更新:
操作步骤:
1. 登录SAE控制台 → 进入应用详情
2. 点击【部署】
3. 修改镜像版本:
从: v1.0.0
到: v1.0.1
4. 点击【确定】
5. 等待部署完成(2-3分钟)
6. 验证新版本:
- 查看实例状态
- 访问前端页面
- 测试核心功能
🔙 回滚操作
如果新版本出现问题,可以快速回滚:
操作步骤:
1. 登录SAE控制台 → 进入应用详情
2. 点击【变更记录】
3. 找到上一个稳定版本(如v1.0.0)
4. 点击【回滚】
5. 确认回滚
6. 等待回滚完成(1-2分钟)
回滚时间:
- 镜像已缓存: 1-2分钟
- 镜像未缓存: 2-3分钟
🗑️ 清理旧版本镜像
定期清理ACR中的旧版本镜像,节省存储空间:
清理策略:
- 保留最近3个版本
- 删除30天前的旧版本
- 保留带有特殊标签的版本(如stable、prod)
操作步骤:
1. 登录ACR控制台
2. 进入镜像仓库 → ai-clinical_frontend-nginx
3. 查看所有版本
4. 选择要删除的版本(勾选)
5. 点击【删除】
6. 确认删除
⚠️ 注意:
- 不要删除正在使用的版本
- 删除前确认SAE应用已更新到新版本
- 建议至少保留2个版本以便回滚
📈 弹性伸缩配置
前端Nginx服务通常不需要频繁扩缩容,但可以配置自动伸缩:
配置位置: 【应用配置】→【弹性伸缩】
最小实例数: 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代理)
- 几乎不需要扩容
🚨 告警配置
配置关键指标告警,及时发现问题:
配置位置: 【云监控】→【应用监控】→【创建告警规则】
推荐告警规则:
1. 实例健康检查失败
- 条件: 健康检查失败 > 3次
- 级别: 紧急
- 通知: 短信 + 钉钉
2. CPU使用率过高
- 条件: CPU > 60% 持续 5分钟
- 级别: 警告
- 通知: 钉钉 + 邮件
3. 内存使用率过高
- 条件: 内存 > 80% 持续 5分钟
- 级别: 警告
- 通知: 钉钉 + 邮件
4. 错误率过高
- 条件: 错误率 > 1% 持续 3分钟
- 级别: 紧急
- 通知: 短信 + 钉钉
5. 平均响应时间过长
- 条件: 响应时间 > 500ms 持续 5分钟
- 级别: 警告
- 通知: 钉钉 + 邮件
通知方式配置:
- 钉钉机器人: 创建群聊机器人,获取Webhook
- 邮件: 配置告警联系人邮箱
- 短信: 配置手机号(建议仅用于紧急告警)
📚 附录
📝 配置文件清单
部署过程中涉及的配置文件:
本地文件 (AIclinicalresearch/frontend-v2/):
- Dockerfile (多阶段构建配置)
- nginx.conf (Nginx服务器配置)
- docker-entrypoint.sh (容器启动脚本)
- .dockerignore (构建排除文件)
SAE配置 (在控制台配置):
- 应用基本信息
- 实例规格和数量
- VPC网络配置
- 镜像地址和版本
- 环境变量
- 健康检查
- 公网访问配置
🔗 相关文档链接
阿里云官方文档:
- 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
💡 最佳实践总结
安全性:
✅ 使用专有网络(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错误日志
- 容器启动日志
🎯 部署检查清单
最后,用这个清单确认部署完成:
部署前准备:
☑️ 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压缩:已启用
监控和告警:
☑️ 实时监控:已配置
☑️ 日志查看:可访问
☑️ 告警规则:已配置
全部完成,部署成功!🎉
文档结束
如有疑问,请查阅相关文档或联系技术支持。
祝部署顺利!🚀