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
34 KiB
AI临床研究平台 - 阿里云快速部署SOP(零基础版)
文档版本: v1.0
创建日期: 2025-12-16
适用场景: 从零开始部署到阿里云(不含Dify)
预计时间: 3-4小时
目标: 系统能够正常访问,基本功能可用
📋 部署检查清单
在开始之前,请确认:
- 已有阿里云账号,且已完成实名认证
- 账户余额 ≥ 500元(建议1000元,包含3个月运行费用)
- 已安装Docker Desktop(用于构建镜像)
- 已安装Git(用于获取代码)
- 本地能够正常运行项目(数据库已初始化)
📌 已部署资源快速参考
以下资源已经在阿里云上部署完成,部署过程中可以直接使用这些信息:
✅ VPC网络信息
VPC ID: vpc-2ze055cptkew9c38w4r06
VPC名称: ai-clinical-vpc
网段: 172.17.0.0/16
地域: 华北2(北京)
交换机ID: vsw-2zevacop039bxrmj6yc0c (可用区F)
vsw-2zehoeyw9ldncymcyvfwq (可用区A)
安全组ID: sg-2zedk6fi8sgmmcwdu7tu
✅ RDS PostgreSQL数据库
实例ID: pgm-2zex1m2y3r23hdn5
内网地址: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432
数据库账号: airesearch
数据库密码: Xibahe@fengzhibo117
数据库名称: ai_clinical_research
规格: 2核4GB (pg.n2.2c.1m)
最大连接数: 400
PostgreSQL版本: 15.0
白名单: 172.17.0.0/16 ✅
时区: Asia/Shanghai ✅
✅ SAE命名空间
命名空间ID: cn-beijing:test-airesearch
地域: 华北2(北京)
✅ OSS对象存储
Bucket名称: ai-clinical-research
地域: 华北2(北京)
存储类型: 标准存储
读写权限: 私有
存储冗余类型: 同城冗余存储
外网Endpoint: oss-cn-beijing.aliyuncs.com
内网Endpoint: oss-cn-beijing-internal.aliyuncs.com
Bucket域名(内网): ai-clinical-research.oss-cn-beijing-internal.aliyuncs.com
创建时间: 2025-12-16 20:22 ✅
# RAM用户访问凭证(用于OSS写入)
RAM用户名: oss-bucket-put-object@1991407246109125.onaliyun.com
AccessKeyId: LTAI5tB2Dt3NdvBL3G7nYGv7
AccessKeySecret: 1iSN9k39RkApP93QjUhC1DcPIeMG4V
UID: 203256565888301026
创建时间: 2025-12-16 20:31:41 ✅
⚠️ 安全警告:AccessKey是敏感信息,请勿提交到公开Git仓库!
✅ NAT网关与公网访问
NAT网关名称: NAT_airesearch
NAT网关ID: ngw-2zeec9ulzgw7ywvx1pst6
SNAT表ID: stb-2zesszmzx1qpwf1cb2bry
公网IP(EIP): 182.92.176.14
创建时间: 2025-12-16 20:58:12 ✅
# SNAT条目配置(2条,覆盖所有交换机)
SNAT条目1:
ID: snat-2zerlp4z0ed2isvq399gn
源网段: 172.17.160.0/20
交换机: vsw-2zevacop039bxrmj6yc0c (可用区F)
公网IP: 182.92.176.14
状态: 可用 ✅
SNAT条目2:
ID: snat-2zegvesjxjwmw7j51m89m
源网段: 172.17.192.0/20
交换机: vsw-2zehoeyw9ldncymcyvfwq (可用区A)
公网IP: 182.92.176.14
状态: 可用 ✅
✅ ACR容器镜像服务
服务类型: 个人版(免费)
命名空间: ai-clinical
用户名: gofeng117@163.com
Registry密码: fengzhibo117
公网域名: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com
专有网络域名: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com
# 镜像仓库(3个)
仓库1 - 前端Nginx:
仓库名称: ai-clinical_frontend-nginx
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx
仓库2 - Python微服务:
仓库名称: python-extraction
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction
仓库3 - Node.js后端:
仓库名称: nodejs-backend
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend
⚠️ 安全警告:Registry密码是敏感信息,请勿提交到公开Git仓库!
⚠️ 待部署资源
- NAT网关 ✅ 已创建,SNAT已配置
- OSS存储桶 ✅ 已创建
- ACR容器镜像仓库 ✅ 已创建
- SAE应用(3个:Python/Node.js/Frontend)
🎯 部署全流程概览
第一阶段:阿里云资源准备(60分钟)
├── 创建VPC网络
├── 创建NAT网关(关键!)
├── 购买RDS PostgreSQL
├── 创建OSS存储桶
└── 创建SAE应用(3个空应用)
第二阶段:数据库初始化(30分钟)
├── 导出本地数据库
├── 通过ECS跳板机连接RDS
└── 导入数据到RDS
第三阶段:Docker镜像准备(60分钟)
├── 创建阿里云容器镜像服务(ACR)
├── 构建Python微服务镜像
├── 构建Node.js后端镜像
└── 构建前端Nginx镜像
第四阶段:SAE应用部署(60分钟)
├── 部署Python微服务
├── 部署Node.js后端
└── 部署前端Nginx
第五阶段:验证与测试(30分钟)
├── 健康检查
├── 功能测试
└── 日志排查
总预计时间:3.5-4小时
第一阶段:阿里云资源准备(60分钟)
1.1 创建VPC专有网络(10分钟)
目的: 为所有云资源提供内网隔离环境
操作步骤:
- 登录阿里云控制台:https://vpc.console.aliyun.com/
- 点击【创建专有网络】
- 填写配置:
名称: ai-clinical-vpc
地域: 华北2(北京)
IPv4网段: 172.17.0.0/16
- 创建交换机(vSwitch):
名称: ai-clinical-vswitch-1
可用区: 北京 可用区H
IPv4网段: 172.17.0.0/20
- 点击【确定】,等待创建完成(约30秒)
验证: 在VPC列表中看到"ai-clinical-vpc",状态为"可用"
1.2 创建NAT网关(15分钟)⭐⭐⭐⭐⭐
目的: 为SAE容器提供公网访问能力(调用DeepSeek/OpenAI API必需)
⚠️ 重要警告: 没有NAT网关,AI功能100%超时!
✅ 实际NAT网关信息(已部署):
NAT网关名称: NAT_airesearch
NAT网关ID: ngw-2zeec9ulzgw7ywvx1pst6
地域: 华北2(北京)
VPC: vpc-2ze055cptkew9c38w4r06
SNAT表ID: stb-2zesszmzx1qpwf1cb2bry
创建时间: 2025-12-16 20:58:12 ✅
# 弹性公网IP (EIP)
公网IP: 182.92.176.14 ✅
# SNAT条目配置(2条,覆盖所有交换机)
SNAT条目1:
ID: snat-2zerlp4z0ed2isvq399gn
源网段: 172.17.160.0/20
交换机: vsw-2zevacop039bxrmj6yc0c (可用区F)
公网IP: 182.92.176.14
状态: ✅ 可用
SNAT条目2:
ID: snat-2zegvesjxjwmw7j51m89m
源网段: 172.17.192.0/20
交换机: vsw-2zehoeyw9ldncymcyvfwq (可用区A)
公网IP: 182.92.176.14
状态: ✅ 可用
⚠️ 如果需要重新创建,操作步骤:
- 进入NAT网关控制台:https://vpc.console.aliyun.com/nat
- 点击【创建NAT网关】
- 填写配置:
地域: 华北2(北京)
VPC: ai-clinical-vpc (vpc-2ze055cptkew9c38w4r06)
规格: 小型(默认,¥60/月)
计费方式: 按量付费
-
购买弹性公网IP(EIP):
- 点击【绑定弹性公网IP】
- 选择【购买并绑定EIP】
- 带宽:5Mbps(按使用流量计费)
- 点击【确定】
-
配置SNAT规则(让SAE能访问公网):
- 点击【SNAT管理】→【创建SNAT条目】
- 选择交换机:为每个交换机创建SNAT条目
- 交换机1:
vsw-2zevacop039bxrmj6yc0c(可用区F) - 交换机2:
vsw-2zehoeyw9ldncymcyvfwq(可用区A) - 选择公网IP:绑定的EIP
- 点击【确定】
验证:
- ✅ NAT网关状态为"运行中"
- ✅ EIP已绑定:182.92.176.14
- ✅ SNAT条目状态为"可用"(2条)
- ✅ 覆盖了所有交换机的网段
成本估算:
- NAT网关:¥60/月
- EIP:¥0.8/GB流量(预计¥40/月)
- 合计:约¥100/月
1.3 购买RDS PostgreSQL数据库(20分钟)
目的: 托管的PostgreSQL数据库,支持10个Schema隔离
操作步骤:
- 进入RDS控制台:https://rdsnext.console.aliyun.com/
- 点击【创建实例】
- 填写配置:
付费类型: 包年包月(首月¥70)
地域: 华北2(北京)
可用区: 北京 可用区H
数据库类型: PostgreSQL
版本: 15
系列: 基础版(节省成本,不支持主备切换)
规格:
- CPU: 2核
- 内存: 4GB
- 存储: 50GB(云盘ESSD)
网络类型: 专有网络(VPC)
VPC: ai-clinical-vpc (vpc-2ze055cptkew9c38w4r06)
交换机: ai-clinical-vswitch-1 (vsw-2zevacop039bxrmj6yc0c)
- 高级配置:
数据库账号: airesearch
密码: (设置复杂密码,记录到密码管理器,如:Xibahe@fengzhibo117)
数据库名称: ai_clinical_research
字符集: UTF8
- 点击【立即购买】,等待创建(约5分钟)
⚠️ 关键配置(创建后):
-
白名单配置(必须配置,否则无法连接):
- 进入实例详情 → 数据安全性 → 白名单设置
- 点击【修改】
- 添加:
172.17.0.0/16(整个VPC网段,不要用单机IP!) - 点击【确定】
-
时区配置(避免日志时间错乱):
- 进入实例详情 → 参数设置
- 搜索:
timezone - 修改值:
Asia/Shanghai - 点击【提交参数】
- ✅ 已配置(可维护时间窗:02:00-06:00 Asia/Shanghai UTC+8)
✅ 实际RDS信息(已部署):
实例ID: pgm-2zex1m2y3r23hdn5
内网地址: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432
数据库账号: airesearch
数据库密码: Xibahe@fengzhibo117
数据库名称: ai_clinical_research
VPC: vpc-2ze055cptkew9c38w4r06 (172.17.0.0/16)
资源组ID: rg-acfm4nrrfnu6tri
规格: 2核4GB (pg.n2.2c.1m)
最大连接数: 400
最大IOPS: 7550
PostgreSQL版本: 15.0
存储类型: 高性能云盘
白名单: 172.17.0.0/16 ✅
时区: Asia/Shanghai (UTC+8) ✅
验证:
- ✅ 实例状态为"运行中"
- ✅ 白名单已包含VPC网段 (172.17.0.0/16)
- ✅ 时区已设置为 Asia/Shanghai
- ✅ 可维护时间窗:02:00-06:00(夜间维护不影响白天使用)
1.4 创建OSS存储桶(10分钟)
目的: 存储文献PDF、稿件文档等文件
✅ 实际OSS信息(已部署):
Bucket名称: ai-clinical-research
地域: 华北2(北京)
存储类型: 标准存储
读写权限: 私有
存储冗余类型: 同城冗余存储
外网Endpoint: oss-cn-beijing.aliyuncs.com
内网Endpoint: oss-cn-beijing-internal.aliyuncs.com
Bucket域名(内网): ai-clinical-research.oss-cn-beijing-internal.aliyuncs.com
创建时间: 2025-12-16 20:22 ✅
访问控制: 文件不可以被公共访问 ✅
⚠️ 如果需要重新创建,操作步骤:
- 进入OSS控制台:https://oss.console.aliyun.com/
- 点击【创建Bucket】
- 填写配置:
Bucket名称: ai-clinical-research(全局唯一)
地域: 华北2(北京)
存储类型: 标准存储
读写权限: 私有(默认)
存储冗余类型: 同城冗余存储(推荐)
版本控制: 不开启
- 推荐的目录结构(应用会自动创建):
asl/ # AI文献筛选模块
├── source/ # 原始PDF文件
└── extracted/ # 解析结果JSON
pkb/ # 个人知识库模块
└── documents/ # 知识库文档
dc/ # 数据清洗模块
├── raw/ # 原始数据文件
└── cleaned/ # 清洗后的数据
- OSS访问授权配置
✅ 方案A:使用AccessKey(已创建,推荐初期使用)
RAM用户: oss-bucket-put-object@1991407246109125.onaliyun.com
AccessKeyId: LTAI5tB2Dt3NdvBL3G7nYGv7
AccessKeySecret: 1iSN9k39RkApP93QjUhC1DcPIeMG4V
权限: OSS Bucket写入权限
⚠️ 安全警告:
- AccessKey是敏感信息,等同于密码
- 请勿将AccessKey提交到Git仓库
- 只在SAE环境变量中配置,不要写入代码
- 定期轮换AccessKey(建议每3个月)
方案B:使用RAM角色(推荐生产环境)
- 进入RAM控制台:https://ram.console.aliyun.com/
- 创建角色:AliyunSAEDefaultRole(SAE默认角色)
- 授予权限:AliyunOSSFullAccess
- 优势:无需管理AccessKey,更安全
验证:
- ✅ Bucket已创建成功
- ✅ 内网Endpoint:
oss-cn-beijing-internal.aliyuncs.com - ✅ Bucket域名:
ai-clinical-research.oss-cn-beijing-internal.aliyuncs.com - ✅ RAM用户已创建,AccessKey已生成
1.5 创建容器镜像服务ACR(5分钟)
目的: 存储Docker镜像,供SAE拉取部署
✅ 实际ACR信息(已部署):
服务类型: 个人版(免费)
命名空间: ai-clinical
用户名: gofeng117@163.com
Registry密码: fengzhibo117
公网域名: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com
专有网络域名: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com
# 镜像仓库(3个)
仓库1 - 前端Nginx:
仓库名称: ai-clinical_frontend-nginx
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx
类型: 私有
状态: ✅ 已创建
仓库2 - Python微服务:
仓库名称: python-extraction
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction
类型: 私有
状态: ✅ 已创建
仓库3 - Node.js后端:
仓库名称: nodejs-backend
公网地址: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend
专有网络地址: crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend
类型: 私有
状态: ✅ 已创建
⚠️ 如果需要重新创建,操作步骤:
- 进入容器镜像服务控制台:https://cr.console.aliyun.com/
- 选择【个人版】(免费)
- 设置Registry密码(用于docker login)
- 创建命名空间:
ai-clinical - 创建3个镜像仓库(类型:私有,代码源:本地仓库)
验证:
- ✅ 3个仓库创建成功
- ✅ Registry地址:
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com - ✅ 专有网络地址:
crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com
⚠️ 安全警告:
- Registry密码是敏感信息,等同于Docker镜像访问权限
- 请勿将密码提交到Git仓库
- 定期轮换密码(建议每3个月)
第二阶段:数据库初始化(30分钟)
2.1 导出本地数据库(5分钟)
在本地项目根目录执行:
# 确保Docker正在运行
docker ps
# 导出数据库
docker exec ai-clinical-postgres pg_dump \
-U postgres \
-d ai_clinical_research \
--no-owner \
--no-acl \
--clean \
--if-exists \
> rds_init.sql
# 验证文件大小(应该有几百KB)
ls -lh rds_init.sql
验证: rds_init.sql 文件存在,且大小 > 100KB
2.2 通过ECS跳板机连接RDS(15分钟)
⚠️ 为什么需要跳板机?
- RDS在VPC内网,本地电脑无法直接连接
- 需要一台ECS服务器作为"桥梁"
操作步骤:
方案A:使用现有Dify ECS(如果已有)
跳过ECS创建步骤,直接使用Dify的ECS作为跳板机。
方案B:创建临时ECS(推荐初期使用)
- 进入ECS控制台,创建按量付费实例:
地域: 华北2(北京)
规格: ecs.t6-c1m1.large(1核1GB,¥0.05/小时)
镜像: Ubuntu 22.04
网络: ai-clinical-vpc (vpc-2ze055cptkew9c38w4r06) / ai-clinical-vswitch-1
安全组: sg-2zedk6fi8sgmmcwdu7tu(允许22端口SSH)
购买时长: 按量付费
- 在本地创建SSH隧道:
# 替换以下参数:
# - ECS_PUBLIC_IP: ECS的公网IP
ssh -N -L 5433:pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432 \
root@ECS_PUBLIC_IP
# 输入ECS密码,成功后命令会"卡住"(正常现象)
# 保持这个终端窗口打开
验证: 打开新终端,执行:
# 测试RDS连接(通过SSH隧道)
psql -h localhost -p 5433 -U airesearch -d ai_clinical_research
# 输入密码:Xibahe@fengzhibo117
# 如果成功连接,说明隧道已建立
2.3 导入数据到RDS(10分钟)
在新终端窗口执行:
# 导入数据(通过SSH隧道)
psql -h localhost -p 5433 \
-U airesearch \
-d ai_clinical_research \
-f rds_init.sql
# 输入密码:Xibahe@fengzhibo117
# 验证导入成功
psql -h localhost -p 5433 \
-U airesearch \
-d ai_clinical_research \
-c "\dt platform_schema.*"
# 应该看到 platform_schema 下的表
验证:
- 看到
platform_schema.users表 - 看到
aia_schema.*表 - 看到
_prisma_migrations表
⚠️ 重要: pg-boss的6个表(job/queue等)不在导出文件中,会在应用首次启动时自动创建。
第三阶段:Docker镜像构建与推送(60分钟)
3.1 登录阿里云容器镜像服务
在本地终端执行:
# 登录ACR个人版(使用真实信息)
docker login --username=gofeng117@163.com crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com
# 输入密码:fengzhibo117
# 看到 "Login Succeeded" 表示登录成功
⚠️ 注意事项:
- 个人版使用自定义域名,不是标准的
registry.cn-beijing.aliyuncs.com - 用户名:
gofeng117@163.com(完整邮箱地址) - 密码:
fengzhibo117(Registry密码,不是阿里云账号密码)
3.2 构建Python微服务镜像(15分钟)
在项目根目录执行:
cd extraction_service
# 构建镜像(确保Dockerfile存在)
docker build -t ai-clinical/python-extraction:v1.0.0 .
# 打标签(使用真实ACR地址)
docker tag ai-clinical/python-extraction:v1.0.0 \
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.0.0
docker tag ai-clinical/python-extraction:v1.0.0 \
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:latest
# 推送到ACR
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.0.0
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:latest
cd ..
验证:
- 在ACR控制台看到镜像,标签为
v1.0.0和latest - 镜像地址:
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.0.0
3.3 构建Node.js后端镜像(20分钟)
⚠️ 重要前置步骤:复制Prisma目录
# 在项目根目录执行
cp -r prisma backend/
# 验证
ls backend/prisma/schema.prisma # 应该存在
构建镜像:
cd backend
# 构建镜像
docker build -t ai-clinical/nodejs-backend:v1.0.0 .
# 打标签并推送(使用真实ACR地址)
docker tag ai-clinical/nodejs-backend:v1.0.0 \
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:v1.0.0
docker tag ai-clinical/nodejs-backend:v1.0.0 \
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:latest
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:v1.0.0
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:latest
cd ..
验证:
- ACR控制台看到Node.js镜像
- 镜像地址:
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:v1.0.0
3.4 构建前端Nginx镜像(25分钟)
在项目根目录执行:
cd frontend-v2
# 构建镜像(包含React构建 + Nginx打包)
docker build -t ai-clinical/frontend-nginx:v1.0.0 .
# 打标签并推送(使用真实ACR地址,注意仓库名称带下划线)
docker tag ai-clinical/frontend-nginx:v1.0.0 \
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0
docker tag ai-clinical/frontend-nginx:v1.0.0 \
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.0
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:latest
cd ..
⚠️ 注意: 前端仓库名称是 ai-clinical_frontend-nginx(带下划线),与后端不同。
验证:
- ACR控制台看到3个镜像仓库,每个都有
v1.0.0和latest标签 - 前端镜像地址:
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0
第四阶段:SAE应用部署(60分钟)
4.1 部署Python微服务(15分钟)
操作步骤:
- 进入SAE控制台:https://sae.console.aliyun.com/
- 点击【创建应用】
- 基础配置:
应用名称: python-extraction-service
命名空间: cn-beijing:test-airesearch(已创建)
地域: 华北2(北京)
VPC: ai-clinical-vpc (vpc-2ze055cptkew9c38w4r06)
安全组: sg-2zedk6fi8sgmmcwdu7tu
- 应用配置:
技术栈: 容器镜像
镜像: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.0.0
镜像拉取策略: Always(重要!)
版本: v1.0.0
⚠️ 重要: 使用个人版ACR地址,不是标准的 registry.cn-beijing.aliyuncs.com
- 应用实例:
CPU: 1核
内存: 2GB
实例数: 1
- 高级配置:
端口: 8000
健康检查: HTTP
- 路径: /health
- 初始延迟: 30秒
- 超时: 3秒
- 检查间隔: 5秒
环境变量: (暂时为空,Python微服务是纯计算服务)
- 点击【创建】,等待部署(约5分钟)
验证:
- 应用状态为"运行中"
- 健康检查通过
- 记录内网地址(格式:
172.17.x.x:8000)
4.2 部署Node.js后端(20分钟)
操作步骤:
- 创建新应用:
nodejs-backend-service - 应用配置:
镜像: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/nodejs-backend:v1.0.0
镜像拉取策略: Always
CPU: 2核
内存: 4GB
实例数: 1
端口: 3001
⚠️ 重要: 使用个人版ACR地址
- 环境变量配置(⭐⭐⭐⭐⭐ 重要):
# ==================== 数据库配置 ====================
# ⚠️ 注意:密码中的 @ 符号必须转义为 %40
DATABASE_URL=postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research
# ✅ 已使用实际RDS信息(密码已转义)
# ==================== 存储配置 ====================
STORAGE_TYPE=oss
OSS_REGION=oss-cn-beijing
OSS_BUCKET=ai-clinical-research
OSS_ENDPOINT=oss-cn-beijing-internal.aliyuncs.com
# ✅ OSS配置已使用实际Bucket信息
# Bucket域名: ai-clinical-research.oss-cn-beijing-internal.aliyuncs.com
# OSS访问凭证(方案A:使用AccessKey)
OSS_ACCESS_KEY_ID=LTAI5tB2Dt3NdvBL3G7nYGv7
OSS_ACCESS_KEY_SECRET=1iSN9k39RkApP93QjUhC1DcPIeMG4V
# ⚠️ 注意:AccessKey是敏感信息,请勿提交到Git!
# OSS访问凭证(方案B:使用RAM角色,更安全)
# 在SAE控制台配置RAM角色:AliyunSAEDefaultRole
# 优势:无需在环境变量中配置AccessKey
# ==================== 微服务地址 ====================
EXTRACTION_SERVICE_URL=http://172.17.x.x:8000
# ⚠️ 替换:172.17.x.x(从Python微服务控制台获取内网IP)
DIFY_API_URL=http://placeholder/v1
DIFY_API_KEY=temp_placeholder
# ⚠️ 暂不部署Dify,使用占位符(PKB模块会自动禁用)
# ==================== LLM配置 ====================
DEEPSEEK_API_KEY=sk-xxxxxxxx
# ⚠️ 替换为真实的DeepSeek API Key
# ==================== 应用配置 ====================
NODE_ENV=production
PORT=3001
- 启动命令(重要!):
/bin/sh -c "npx prisma migrate deploy && node dist/index.js"
⚠️ 说明:
npx prisma migrate deploy:部署数据库迁移node dist/index.js:启动应用
- 健康检查:
路径: /health
初始延迟: 60秒(留时间给Prisma迁移)
超时: 5秒
- 点击【创建】,等待部署(约10分钟)
验证:
- 查看"实时日志",看到:
✅ Prisma migrate deploy 完成 ✅ pg-boss 自动创建6个表 ✅ 应用启动成功,监听 0.0.0.0:3001 - 健康检查通过
- 记录内网地址(格式:
172.17.x.x:3001)
⚠️ 如果启动失败:
常见原因:
- DATABASE_URL错误 → 检查密码、RDS地址
- 当前RDS:pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com
- 用户名:airesearch
- 密码中有特殊字符@,URL中需要转义为 %40
- 白名单未配置 → ✅ 已确认配置:172.17.0.0/16
- Prisma迁移失败 → 查看日志,确认数据库权限
⚠️ 密码特殊字符转义(重要):
# 原始密码:Xibahe@fengzhibo117
# @ 符号需要转义为 %40
# 错误写法(会导致连接失败):
DATABASE_URL=postgresql://airesearch:Xibahe@fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research
# 正确写法:
DATABASE_URL=postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research
4.3 部署前端Nginx(15分钟)
操作步骤:
- 创建新应用:
frontend-nginx - 应用配置:
镜像: crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.0.0
镜像拉取策略: Always
CPU: 1核
内存: 2GB
实例数: 1
端口: 80
⚠️ 重要:
- 使用个人版ACR地址
- 注意仓库名称是
ai-clinical_frontend-nginx(带下划线)
- 环境变量配置:
# 后端服务地址(内网)
BACKEND_SERVICE_HOST=172.17.x.x
BACKEND_SERVICE_PORT=3001
# ⚠️ 替换:172.17.x.x(从Node.js后端控制台获取内网IP)
- 健康检查:
路径: /health
初始延迟: 10秒
超时: 3秒
-
配置公网访问(重要!):
- 在应用详情 → 基本信息 → 公网访问
- 点击【开启】
- 获得公网域名(格式:
xxxx.cn-beijing.alicontainer.com)
-
点击【创建】,等待部署(约5分钟)
验证:
- 应用状态为"运行中"
- 通过公网域名访问,看到登录页面
第五阶段:验证与测试(30分钟)
5.1 健康检查验证(5分钟)
Python微服务:
# 在本地终端执行(替换为实际公网地址,如果开启了)
# 或通过Node.js后端间接验证
# 直接测试(如果Python开启了公网)
curl http://python-service-public-url/health
# 预期响应:
{"status":"healthy"}
Node.js后端:
curl http://backend-public-url/health
# 预期响应:
{"status":"ok","database":"connected","timestamp":"..."}
前端Nginx:
curl http://frontend-public-url/health
# 预期响应:
{"status":"ok"}
5.2 功能测试(15分钟)
5.2.1 用户登录测试
- 访问前端公网地址:
http://xxxxx.cn-beijing.alicontainer.com - 使用测试账号登录:
- 账号:
admin@test.com - 密码:
admin123(或你本地数据库中的密码)
- 账号:
- 验证:成功跳转到主页,显示用户名
5.2.2 文献筛选测试(ASL模块)
- 进入【AI智能文献】模块
- 创建新项目:
项目名称: 测试项目 研究主题: 糖尿病治疗 - 上传测试文献(小文件,< 5MB)
- 验证:
- 文件上传到OSS成功
- 后端调用Python服务解析PDF
- 数据库中生成记录
5.2.3 数据清洗测试(DC模块)
- 进入【数据清洗】模块
- 上传测试Excel文件
- 验证:
- OSS上传成功
- Python服务处理数据
- 下载清洗结果
5.3 日志排查(10分钟)
查看SAE实时日志
Python微服务:
SAE控制台 → python-extraction-service → 日志 → 实时日志
查看是否有错误日志(ERROR/WARN)
Node.js后端:
SAE控制台 → nodejs-backend-service → 日志 → 实时日志
关键日志:
✅ Prisma connected
✅ pg-boss started
✅ Server listening on 0.0.0.0:3001
前端Nginx:
SAE控制台 → frontend-nginx → 日志 → 访问日志
查看HTTP请求日志(200/404/500状态码)
🚨 常见问题与解决方案
问题1:后端无法连接数据库
症状: Node.js日志显示 connection timeout 或 FATAL: no pg_hba.conf entry
解决方案:
-
检查RDS白名单:
RDS控制台 → 数据安全性 → 白名单设置 确保包含:172.17.0.0/16(VPC网段) -
检查DATABASE_URL:
# ✅ 正确格式(特殊字符已转义): postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research # 常见错误: - 密码中的 @ 符号未转义为 %40(最常见!) - RDS地址错误(应该用内网地址) - 数据库名称错误 # 特殊字符转义规则: @ -> %40 # -> %23 $ -> %24 % -> %25
问题2:后端调用Python微服务超时
症状: 日志显示 ECONNREFUSED 或 timeout
解决方案:
-
检查Python微服务内网地址:
SAE控制台 → python-extraction-service → 基本信息 → 内网地址 复制IP地址(格式:172.17.x.x) -
更新Node.js后端环境变量:
EXTRACTION_SERVICE_URL=http://172.17.x.x:8000 -
重启Node.js后端应用
问题3:前端调用后端404
症状: 浏览器控制台显示 /api/xxx 404
解决方案:
-
检查前端环境变量:
# 确认 BACKEND_SERVICE_HOST 是Node.js的内网IP BACKEND_SERVICE_HOST=172.17.x.x BACKEND_SERVICE_PORT=3001 -
检查Nginx配置(已内置在镜像中):
location /api/ { proxy_pass http://${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT}; } -
重启前端应用
问题4:文件上传到OSS失败
症状: 上传文件时报错 OSS access denied
解决方案:
-
方案A:使用AccessKey(已配置)
# 确认Node.js后端环境变量已配置: OSS_ACCESS_KEY_ID=LTAI5tB2Dt3NdvBL3G7nYGv7 OSS_ACCESS_KEY_SECRET=1iSN9k39RkApP93QjUhC1DcPIeMG4V验证方法:
- SAE控制台 → nodejs-backend-service → 应用设置 → 环境变量
- 检查是否包含
OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET
-
方案B:使用RAM角色(推荐生产环境)
SAE控制台 → 应用设置 → 高级设置 → RAM角色 选择:AliyunSAEDefaultRole 确保该角色有 AliyunOSSFullAccess 权限优势:
- 无需在环境变量中配置AccessKey
- 更安全,避免AccessKey泄露风险
- 支持自动轮换凭证
-
检查RAM用户权限:
RAM控制台 → 用户 → oss-bucket-put-object@1991407246109125.onaliyun.com 确认权限:PutObject(写入权限)
问题5:AI功能无法调用(DeepSeek API超时)
症状: LLM对话功能报错 network timeout
解决方案:
-
检查NAT网关SNAT规则:
VPC控制台 → NAT网关 → NAT_airesearch → SNAT管理 ✅ 已确认配置: - 交换机F (vsw-2zevacop039bxrmj6yc0c): 172.17.160.0/20 → 182.92.176.14 (可用) - 交换机A (vsw-2zehoeyw9ldncymcyvfwq): 172.17.192.0/20 → 182.92.176.14 (可用) -
验证公网访问能力:
# 在SAE应用实例中执行命令(通过WebIDE): curl https://api.deepseek.com/v1/models # 应该返回模型列表,而不是 timeout -
如果SNAT未生效:
- 检查EIP是否已绑定
- 检查SNAT条目状态是否为"可用"
- 重启SAE应用
📊 成本估算
| 资源 | 规格 | 月成本 | 说明 |
|---|---|---|---|
| RDS PostgreSQL | 2核4GB/50GB | ¥200-300 | 包年包月(已购买) |
| SAE - Python | 1核2GB × 1实例 | ¥60 | 按量付费(闲时¥0) |
| SAE - Node.js | 2核4GB × 1实例 | ¥120 | 按量付费 |
| SAE - Frontend | 1核2GB × 1实例 | ¥60 | 按量付费 |
| NAT网关 | 小型 | ¥60 | 固定费用(已创建) |
| EIP流量费 | 5Mbps | ¥40 | 按使用量计费(已配置) |
| OSS存储 | 10GB | ¥2 | ¥0.12/GB/月(已创建) |
| ACR容器镜像 | 个人版 | ¥0 | 免费 |
| 总计 | - | ¥542-622/月 | 初创团队成本 |
节省成本建议:
- RDS购买包年包月(首月¥70,续费¥200/月)
- 开发环境只开1个SAE实例(其他实例缩容到0)
- 使用SAE的"闲时停机"功能(晚上自动停机)
🎯 下一步工作
短期(1周内)
- 绑定自定义域名(阿里云域名服务 + SAE绑定)
- 配置HTTPS证书(Let's Encrypt免费证书)
- 配置OSS CDN加速(前端静态资源加速)
- 开启RDS自动备份(数据安全第一)
中期(1个月内)
- 部署Dify平台(启用PKB个人知识库功能)
- 配置监控告警(ARMS应用监控)
- 优化数据库索引(提升查询性能)
- 实施CI/CD自动化部署(GitHub Actions)
长期(3个月后)
- 多实例部署(提升高可用性)
- 数据库读写分离(RDS主备版)
- OSS生命周期管理(自动清理临时文件)
- 性能优化与成本优化
📚 相关文档
🆘 紧急联系
如果遇到无法解决的问题:
- 查看SAE实时日志(90%的问题能从日志中发现)
- 检查环境变量配置(DATABASE_URL、服务地址等)
- 验证网络连通性(VPC、白名单、NAT网关)
- 参考详细部署文档(每个模块有独立的完整指南)
文档版本: v1.0
最后更新: 2025-12-16
维护者: AI临床研究平台技术团队