Files
AIclinicalresearch/docs/05-部署文档/_archive-2025首次部署/07-前端Nginx-SAE部署操作手册.md
HaHafeng 6124c7abc6 docs(platform): Add database documentation system and restructure deployment docs
Completed:
- Add 6 core database documents (docs/01-平台基础层/07-数据库/)
  Architecture overview, migration history, environment comparison,
  tech debt tracking, seed data management, PostgreSQL extensions
- Restructure deployment docs: archive 20 legacy files to _archive-2025/
- Create unified daily operations manual (01-日常更新操作手册.md)
- Add pending deployment change tracker (03-待部署变更清单.md)
- Update database development standard to v3.0 (three iron rules)
- Fix Prisma schema type drift: align @db.* annotations with actual DB
  IIT: UUID/Timestamptz(6), SSA: Timestamp(6)/VarChar(20/50/100)
- Add migration: 20260227_align_schema_with_db_types (idempotent ALTER)
- Add Cursor Rule for auto-reminding deployment change documentation
- Update system status guide v6.4 with deployment and DB doc references
- Add architecture consultation docs (Prisma guide, SAE deployment guide)

Technical details:
- Manual migration due to shadow DB limitation (TD-001 in tech debt)
- Deployment docs reduced from 20+ scattered files to 3 core documents
- Cursor Rule triggers on schema.prisma, package.json, Dockerfile changes

Made-with: Cursor
2026-02-27 14:35:25 +08:00

1402 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端 Nginx - SAE 部署操作手册
**文档版本**: v1.0
**创建时间**: 2025-12-23
**适用范围**: AIclinicalresearch 平台前端服务
**部署目标**: 阿里云 SAEServerless 应用引擎)
**镜像仓库**: 阿里云 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核4GBPython需要2核4GB
实例数量: 2
说明:
- 最小2个实例保证高可用
- 1个实例故障时另1个继续服务
- 前端很少需要扩容
```
**为什么前端只需要0.5核1GB**
| 服务类型 | 推荐规格 | 原因 |
|---------|---------|------|
| Node.js 后端 | 2核4GB | 处理AI对话、数据库查询、业务逻辑 |
| Python 微服务 | 2核4GB | PDF提取是CPU密集型操作 |
| **Nginx 前端** | **0.5核1GB** | **仅提供静态文件,消耗极少** |
#### **步骤4VPC网络配置**
```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
协议: HTTPSSAE自动配置证书
优点:
- ✅ 免费
- ✅ 自动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次检查 /health10秒后
└─ 标记为健康 ✅
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: 状态200Cache-Control: no-cache
✅ index-xxxxx.js: 状态200Cache-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 <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。
**排查步骤:**
```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
正确示例:
<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/', // ❌ 除非确实需要
})
```
**解决方法:**
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
```
#### **步骤3SAE灰度发布推荐**
```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+ QPSAPI代理
- 几乎不需要扩容
```
---
### 🚨 **告警配置**
配置关键指标告警,及时发现问题:
```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压缩已启用
监控和告警:
☑️ 实时监控:已配置
☑️ 日志查看:可访问
☑️ 告警规则:已配置
全部完成,部署成功!🎉
```
---
**文档结束**
如有疑问,请查阅相关文档或联系技术支持。
祝部署顺利!🚀