feat(iit): Complete REDCap production deployment on Alibaba Cloud ECS

Summary:

- Deploy REDCap 15.8.0 on ECS with Docker CE 26.1.3

- Configure RDS MySQL 8.0 database (redcap_prod)

- Setup Nginx reverse proxy with HTTPS/SSL

- Domain configured: https://redcap.xunzhengyixue.com/

Documentation:

- Add ECS deployment guide

- Add deployment info record

- Update system status document (v4.5 -> v4.6)

Status: REDCap production environment fully operational
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-02 22:27:05 +08:00
parent 4c2c9b437b
commit 4b9b90ffb8
5 changed files with 1162 additions and 10 deletions

View File

@@ -0,0 +1,200 @@
/**
* 对比本地数据库和RDS数据库的差异
*/
const { Client } = require('pg');
// 本地数据库配置
const localConfig = {
host: 'localhost',
port: 5432,
database: 'ai_clinical_research',
user: 'postgres',
password: 'postgres123',
};
// RDS数据库配置测试环境
const rdsConfig = {
host: 'pgm-2zex1m2y3r23hdn5xo.pg.rds.aliyuncs.com', // 外网地址
port: 5432,
database: 'ai_clinical_research_test',
user: 'airesearch',
password: 'Xibahe@fengzhibo117',
connectionTimeoutMillis: 30000,
};
async function getSchemas(client) {
const result = await client.query(`
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast', 'pg_temp_1', 'pg_toast_temp_1')
ORDER BY schema_name
`);
return result.rows.map(r => r.schema_name);
}
async function getTables(client) {
const result = await client.query(`
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
AND table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name
`);
return result.rows.map(r => `${r.table_schema}.${r.table_name}`);
}
async function getExtensions(client) {
const result = await client.query(`
SELECT extname, extversion FROM pg_extension ORDER BY extname
`);
return result.rows;
}
async function main() {
console.log('=' .repeat(60));
console.log('数据库对比工具');
console.log('=' .repeat(60));
// 连接本地数据库
console.log('\n[1] 连接本地数据库...');
const localClient = new Client(localConfig);
try {
await localClient.connect();
console.log('✅ 本地数据库连接成功');
} catch (err) {
console.log('❌ 本地数据库连接失败:', err.message);
return;
}
// 连接RDS数据库
console.log('\n[2] 连接RDS数据库...');
const rdsClient = new Client(rdsConfig);
try {
await rdsClient.connect();
console.log('✅ RDS数据库连接成功');
} catch (err) {
console.log('❌ RDS数据库连接失败:', err.message);
await localClient.end();
return;
}
try {
// 对比 Extensions
console.log('\n' + '=' .repeat(60));
console.log('📦 Extensions 对比');
console.log('=' .repeat(60));
const localExtensions = await getExtensions(localClient);
const rdsExtensions = await getExtensions(rdsClient);
console.log('\n本地 Extensions:');
localExtensions.forEach(e => console.log(` - ${e.extname} (${e.extversion})`));
console.log('\nRDS Extensions:');
rdsExtensions.forEach(e => console.log(` - ${e.extname} (${e.extversion})`));
// 对比 Schemas
console.log('\n' + '=' .repeat(60));
console.log('📁 Schema 对比');
console.log('=' .repeat(60));
const localSchemas = await getSchemas(localClient);
const rdsSchemas = await getSchemas(rdsClient);
const schemasOnlyInLocal = localSchemas.filter(s => !rdsSchemas.includes(s));
const schemasOnlyInRds = rdsSchemas.filter(s => !localSchemas.includes(s));
const commonSchemas = localSchemas.filter(s => rdsSchemas.includes(s));
console.log(`\n共同 Schemas (${commonSchemas.length}个):`);
commonSchemas.forEach(s => console.log(`${s}`));
if (schemasOnlyInLocal.length > 0) {
console.log(`\n⚠️ 仅在本地存在的 Schemas (${schemasOnlyInLocal.length}个):`);
schemasOnlyInLocal.forEach(s => console.log(` 🔴 ${s}`));
}
if (schemasOnlyInRds.length > 0) {
console.log(`\n仅在RDS存在的 Schemas (${schemasOnlyInRds.length}个):`);
schemasOnlyInRds.forEach(s => console.log(` 🟡 ${s}`));
}
// 对比 Tables
console.log('\n' + '=' .repeat(60));
console.log('📊 Table 对比');
console.log('=' .repeat(60));
const localTables = await getTables(localClient);
const rdsTables = await getTables(rdsClient);
const tablesOnlyInLocal = localTables.filter(t => !rdsTables.includes(t));
const tablesOnlyInRds = rdsTables.filter(t => !localTables.includes(t));
console.log(`\n本地表总数: ${localTables.length}`);
console.log(`RDS表总数: ${rdsTables.length}`);
if (tablesOnlyInLocal.length > 0) {
console.log(`\n⚠️ 仅在本地存在的表 (${tablesOnlyInLocal.length}个) - 需要同步到RDS:`);
tablesOnlyInLocal.forEach(t => console.log(` 🔴 ${t}`));
} else {
console.log('\n✅ 没有仅在本地存在的表');
}
if (tablesOnlyInRds.length > 0) {
console.log(`\n仅在RDS存在的表 (${tablesOnlyInRds.length}个):`);
tablesOnlyInRds.forEach(t => console.log(` 🟡 ${t}`));
}
// 检查关键表的字段差异
console.log('\n' + '=' .repeat(60));
console.log('🔍 关键表字段检查');
console.log('=' .repeat(60));
// 检查 prompt_templates 表的 knowledge_config 字段
const checkColumn = async (client, schema, table, column) => {
const result = await client.query(`
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = $1 AND table_name = $2 AND column_name = $3
`, [schema, table, column]);
return result.rows.length > 0;
};
const localHasKnowledgeConfig = await checkColumn(localClient, 'capability_schema', 'prompt_templates', 'knowledge_config');
const rdsHasKnowledgeConfig = await checkColumn(rdsClient, 'capability_schema', 'prompt_templates', 'knowledge_config');
console.log('\ncapability_schema.prompt_templates.knowledge_config:');
console.log(` 本地: ${localHasKnowledgeConfig ? '✅ 存在' : '❌ 不存在'}`);
console.log(` RDS: ${rdsHasKnowledgeConfig ? '✅ 存在' : '❌ 不存在'}`);
// 总结
console.log('\n' + '=' .repeat(60));
console.log('📋 同步建议');
console.log('=' .repeat(60));
const needSync = schemasOnlyInLocal.length > 0 || tablesOnlyInLocal.length > 0 || (localHasKnowledgeConfig && !rdsHasKnowledgeConfig);
if (needSync) {
console.log('\n⚠ 需要同步以下内容到RDS:');
if (schemasOnlyInLocal.length > 0) {
console.log(` - ${schemasOnlyInLocal.length} 个 Schema`);
}
if (tablesOnlyInLocal.length > 0) {
console.log(` - ${tablesOnlyInLocal.length} 个表`);
}
if (localHasKnowledgeConfig && !rdsHasKnowledgeConfig) {
console.log(' - prompt_templates.knowledge_config 字段');
}
console.log('\n建议执行: npx prisma migrate deploy');
} else {
console.log('\n✅ 数据库结构已同步,无需迁移');
}
} finally {
await localClient.end();
await rdsClient.end();
console.log('\n数据库连接已关闭');
}
}
main().catch(console.error);

View File

@@ -1,10 +1,11 @@
# AIclinicalresearch 系统当前状态与开发指南
> **文档版本:** v4.5
> **文档版本:** v4.6
> **创建日期:** 2025-11-28
> **维护者:** 开发团队
> **最后更新:** 2026-01-28
> **最后更新:** 2026-02-02
> **🎉 重大里程碑:**
> - **2026-02-02REDCap 生产环境部署完成!** ECS + RDS + HTTPS + 域名全部配置完成
> - **2026-01-28Prompt 知识库集成完成!** Prompt 可动态引用系统知识库内容
> - **2026-01-27系统知识库管理功能完成** 运营管理端新增知识库管理+文档上传下载
> - **2026-01-25Protocol Agent MVP完整交付** 一键生成研究方案+Word导出
@@ -12,14 +13,15 @@
> - **2026-01-22OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层
> - **2026-01-21成功替换 Dify** PKB 模块完全使用自研 pgvector RAG 引擎
>
> **最新进展(Prompt 知识库集成 2026-01-28**
> - ✅ **PromptService 增强**:支持 FULL/RAG 两种知识库注入模式
> - ✅ **配置界面**Prompt 编辑器右侧面板配置知识库增强
> - ✅ **测试渲染**:预览知识库注入效果
> - ✅ **发布即生效**:发布后业务端立即使用知识库增强
> - ✅ **Bug 修复**:配置保存、发布按钮、缓存清除等问题
> **最新进展(REDCap 生产环境部署 2026-02-02**
> - ✅ **ECS 服务器配置**Docker CE 26.1.3 + Docker Compose v2.27.0
> - ✅ **RDS MySQL 配置**redcap_prod 数据库 + utf8mb4 字符集
> - ✅ **REDCap 15.8.0 部署**Docker 容器化部署,数据库初始化完成
> - ✅ **HTTPS 配置**Nginx 反向代理 + 阿里云 SSL 证书
> - ✅ **域名配置**https://redcap.xunzhengyixue.com/ 正式上线
>
> **部署状态:** ✅ 生产环境运行中 | 公网地址http://8.140.53.236/
> **REDCap 状态:** ✅ 生产环境运行中 | 地址https://redcap.xunzhengyixue.com/
> **文档目的:** 快速了解系统当前状态为新AI助手提供上下文
---
@@ -56,7 +58,7 @@
| **PKB** | 个人知识库 | RAG问答、私人文献库 | ⭐⭐⭐ | 🎉 **Dify已替换自研RAG上线95%** | P1 |
| **ASL** | AI智能文献 | 文献筛选、Meta分析、证据图谱 | ⭐⭐⭐⭐⭐ | 🎉 **智能检索MVP完成60%** - DeepSearch集成 | **P0** |
| **DC** | 数据清洗整理 | ETL + 医学NER百万行级数据 | ⭐⭐⭐⭐⭐ | ✅ **Tool B完成 + Tool C 99%(异步架构+性能优化-99%+多指标转换+7大功能** | **P0** |
| **IIT** | IIT Manager Agent | AI驱动IIT研究助手 - 智能质控+REDCap集成 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 1.5完成60%- AI对话+REDCap数据集** | **P0** |
| **IIT** | IIT Manager Agent | AI驱动IIT研究助手 - 智能质控+REDCap集成 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 2.065%- AI对话+REDCap生产环境部署完** | **P0** |
| **SSA** | 智能统计分析 | 队列/预测模型/RCT分析 | ⭐⭐⭐⭐⭐ | 📋 规划中 | P2 |
| **ST** | 统计分析工具 | 100+轻量化统计工具 | ⭐⭐⭐⭐ | 📋 规划中 | P2 |
| **RVW** | 稿件审查系统 | 方法学评估、审稿流程、Word导出 | ⭐⭐⭐⭐ | ✅ **开发完成95%** | P3 |
@@ -811,6 +813,15 @@ data: [DONE]\n\n
-**代码设计完成**RedcapAdapter、WebhookController、SyncManager
-**REDCap文档体系**部署手册、问题排查、API对接指南
**REDCap生产环境部署完成**2026-02-02**100%**
-**ECS服务器**:阿里云 ecs.u2a-c1m2.large2核4GB公网IP39.105.153.58
-**RDS MySQL**MySQL 8.02核4GB数据库redcap_prod
-**Docker部署**Docker CE 26.1.3 + Docker Compose v2.27.0
-**HTTPS配置**Nginx反向代理 + 阿里云免费SSL证书
-**域名上线**https://redcap.xunzhengyixue.com/
-**管理员账户**:已创建,可正常登录
-**完整文档**:部署方案 + 信息记录 + 问题排查手册
**Day 1 技术验证**
```bash
# 数据库CRUD测试 - 全部通过 ✅

View File

@@ -0,0 +1,621 @@
# REDCap 阿里云 ECS 生产环境部署方案
**版本:** v1.0
**创建日期:** 2026-02-02
**适用环境:** 阿里云 ECS + RDS MySQL 8.0
**REDCap版本** 15.8.0
**状态:** 📋 待执行
---
## 📋 部署概览
### 目标架构
```
┌─────────────────────────────────────────────────────────────┐
│ 阿里云生产环境架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 公网访问层 │ │
│ │ 公网IP: 39.105.153.58:80/443 │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ECS 服务器 (launch-advisor-20260108) │ │
│ │ ├── Docker Engine │ │
│ │ └── REDCap 容器 │ │
│ │ ├── Apache 2.4 + PHP 8.1 │ │
│ │ └── REDCap 15.8.0 │ │
│ │ 私网IP: 172.17.173.82 │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ VPC内网 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ RDS MySQL 8.0 (rm-2ze9587199003517c) │ │
│ │ ├── 2核 4GB │ │
│ │ ├── 数据库: redcap_prod │ │
│ │ └── 用户: redcap_user │ │
│ │ 内网地址: rm-2ze9587199003517c.mysql.rds.aliyuncs.com │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 资源清单
| 资源 | 规格 | 状态 | 备注 |
|------|------|------|------|
| ECS 服务器 | 2核 4GB | ✅ 已购买 | launch-advisor-20260108 |
| RDS MySQL | 2核 4GBMySQL 8.0 | ✅ 已购买 | rm-2ze9587199003517c |
| 公网IP | 39.105.153.58 | ✅ 已分配 | 需配置安全组 |
| 域名 | 待配置 | ⏳ 可选 | 建议使用域名+SSL |
---
## 🚀 部署步骤
### 阶段1ECS 服务器初始化
#### 1.1 SSH 连接到 ECS
```bash
# 方式1使用阿里云控制台"远程连接"
# 方式2本地 SSH 连接
ssh root@39.105.153.58
```
#### 1.2 更新系统
```bash
# 更新系统包
sudo yum update -y
# 安装常用工具
sudo yum install -y git curl wget vim
```
#### 1.3 安装 Docker
```bash
# 安装 Docker
sudo yum install -y docker
# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
docker --version
# 预期输出: Docker version 20.x.x 或更高
# 添加当前用户到 docker 组(可选,避免每次 sudo
sudo usermod -aG docker $USER
```
#### 1.4 安装 Docker Compose
```bash
# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
# 预期输出: Docker Compose version v2.24.0
```
#### 1.5 创建工作目录
```bash
# 创建 REDCap 部署目录
sudo mkdir -p /opt/redcap
sudo chown -R $USER:$USER /opt/redcap
cd /opt/redcap
# 创建子目录
mkdir -p config/{apache,php}
mkdir -p logs
```
---
### 阶段2RDS MySQL 配置
#### 2.1 配置 RDS 白名单
**在阿里云 RDS 控制台操作:**
1. 进入 RDS 实例详情页
2. 左侧菜单 → "白名单与安全组"
3. 点击"修改",添加 ECS 私网 IP
```
172.17.173.82
```
4. 保存
#### 2.2 获取 RDS 内网连接地址
**在 RDS 控制台 → "数据库连接" 页面获取:**
```
内网地址: rm-2ze9587199003517c.mysql.rds.aliyuncs.com
端口: 3306
```
#### 2.3 创建 REDCap 数据库和用户
**方式1使用阿里云 DMS 控制台**
1. RDS 控制台 → 点击"登录数据库"
2. 执行以下 SQL
```sql
-- 创建数据库
CREATE DATABASE redcap_prod
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 创建用户(使用强密码!)
CREATE USER 'redcap_user'@'172.17.173.%'
IDENTIFIED BY 'YOUR_STRONG_PASSWORD_32_CHARS_MIN';
-- 授予权限
GRANT ALL PRIVILEGES ON redcap_prod.* TO 'redcap_user'@'172.17.173.%';
FLUSH PRIVILEGES;
-- 验证
SHOW DATABASES;
SELECT User, Host FROM mysql.user WHERE User = 'redcap_user';
```
**方式2从 ECS 使用 mysql 客户端**
```bash
# 安装 MySQL 客户端
sudo yum install -y mysql
# 连接 RDS使用 root 账户)
mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com -u root -p
# 执行上述 SQL
```
#### 2.4 记录数据库连接信息
```
主机: rm-2ze9587199003517c.mysql.rds.aliyuncs.com
端口: 3306
数据库: redcap_prod
用户名: redcap_user
密码: YOUR_STRONG_PASSWORD_32_CHARS_MIN
```
---
### 阶段3准备 REDCap 文件
#### 3.1 上传 REDCap 源码
**方式1使用 SCP 从本地上传**
```powershell
# 在本地 Windows PowerShell 执行
scp -r D:\MyCursor\Redcap\redcap15.8.0 root@39.105.153.58:/opt/redcap/
```
**方式2使用阿里云 OSS 中转**
1. 上传 redcap15.8.0.zip 到 OSS
2. 在 ECS 下载:
```bash
cd /opt/redcap
wget https://your-bucket.oss-cn-beijing.aliyuncs.com/redcap15.8.0.zip
unzip redcap15.8.0.zip
```
#### 3.2 上传 Docker 配置文件
```powershell
# 在本地 Windows PowerShell 执行
scp D:\MyCursor\Redcap\redcap-docker-dev\Dockerfile.redcap root@39.105.153.58:/opt/redcap/
scp D:\MyCursor\Redcap\redcap-docker-dev\docker-entrypoint.sh root@39.105.153.58:/opt/redcap/
scp D:\MyCursor\Redcap\redcap-docker-dev\config\php\php.ini root@39.105.153.58:/opt/redcap/config/php/
scp D:\MyCursor\Redcap\redcap-docker-dev\config\apache\redcap.conf root@39.105.153.58:/opt/redcap/config/apache/
```
#### 3.3 创建生产环境 database.php
在 ECS 上创建:
```bash
cat > /opt/redcap/config/database.php << 'EOF'
<?php
/**
* REDCap 生产环境数据库配置
* 环境: 阿里云 ECS + RDS MySQL 8.0
* 创建日期: 2026-02-02
*/
// RDS MySQL 连接信息
$hostname = 'rm-2ze9587199003517c.mysql.rds.aliyuncs.com';
$db = 'redcap_prod';
$username = 'redcap_user';
$password = 'YOUR_STRONG_PASSWORD_32_CHARS_MIN'; // ⚠️ 修改为实际密码
// Salt值 - ⚠️ 重要:设置后永不可变!
$salt = 'YOUR_RANDOM_SALT_32_CHARS_NEVER_CHANGE'; // ⚠️ 修改为随机字符串
// 高级配置(可选)
$db_ssl_verify_server_cert = false; // RDS 内网连接可不验证
// 以下配置保持默认
$homepage_contact = 'admin@example.com';
$homepage_contact_url = '';
EOF
```
**⚠️ 重要生成强密码和Salt**
```bash
# 生成随机密码32字符
openssl rand -base64 32
# 生成 Salt建议64字符
openssl rand -base64 48
```
#### 3.4 创建生产环境 docker-compose.prod.yml
```bash
cat > /opt/redcap/docker-compose.prod.yml << 'EOF'
# REDCap Docker Compose 配置 - 生产环境
# 版本v1.0
# 日期2026-02-02
# 用途:阿里云 ECS + RDS MySQL 生产环境
version: '3.8'
services:
# ========== REDCap Web服务 (Apache + PHP 8.1) ==========
redcap-web:
build:
context: .
dockerfile: Dockerfile.redcap
container_name: redcap-prod
restart: always
ports:
- "80:80"
# - "443:443" # HTTPS配置SSL后启用
volumes:
# REDCap源代码只读
- ./redcap15.8.0/redcap:/var/www/html/redcap:ro
# 配置文件
- ./config/apache/redcap.conf:/etc/apache2/sites-available/000-default.conf:ro
- ./config/php/php.ini:/usr/local/etc/php/php.ini:ro
- ./config/database.php:/var/www/html/redcap/database.php:ro
# 持久化数据(可读写)
- redcap-edocs:/var/www/html/redcap/edocs
- redcap-modules:/var/www/html/redcap/modules
- redcap-temp:/var/www/html/redcap/temp
# 日志
- ./logs:/var/log/apache2
environment:
TZ: Asia/Shanghai
# RDS 连接信息(用于健康检查)
REDCAP_DB_HOST: rm-2ze9587199003517c.mysql.rds.aliyuncs.com
REDCAP_DB_PORT: 3306
REDCAP_DB_NAME: redcap_prod
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
# ========== 数据卷配置 ==========
volumes:
# REDCap上传文件重要需定期备份
redcap-edocs:
name: redcap-edocs-prod
driver: local
# External Modules
redcap-modules:
name: redcap-modules-prod
driver: local
# 临时文件
redcap-temp:
name: redcap-temp-prod
driver: local
EOF
```
#### 3.5 确保脚本有执行权限
```bash
chmod +x /opt/redcap/docker-entrypoint.sh
```
---
### 阶段4配置安全组
#### 4.1 ECS 安全组规则
**在阿里云 ECS 控制台 → 安全组 配置:**
| 规则方向 | 协议 | 端口 | 授权对象 | 说明 |
|---------|------|------|---------|------|
| 入方向 | TCP | 80 | 0.0.0.0/0 | HTTP访问 |
| 入方向 | TCP | 443 | 0.0.0.0/0 | HTTPS访问可选 |
| 入方向 | TCP | 22 | 您的IP/32 | SSH管理限制IP |
| 出方向 | TCP | 3306 | 172.17.0.0/16 | 访问RDS |
| 出方向 | TCP | 443 | 0.0.0.0/0 | HTTPS出站 |
**⚠️ 安全建议:**
- SSH 端口22建议限制为您的办公网络 IP
- 不要开放 3306 端口到公网
---
### 阶段5部署 REDCap
#### 5.1 验证文件结构
```bash
cd /opt/redcap
ls -la
# 预期结构:
# /opt/redcap/
# ├── Dockerfile.redcap
# ├── docker-compose.prod.yml
# ├── docker-entrypoint.sh
# ├── config/
# │ ├── apache/redcap.conf
# │ ├── php/php.ini
# │ └── database.php
# ├── redcap15.8.0/
# │ └── redcap/
# └── logs/
```
#### 5.2 测试数据库连接
```bash
# 测试 RDS 连接
mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \
-u redcap_user -p \
-e "SELECT 1;"
```
#### 5.3 构建并启动容器
```bash
cd /opt/redcap
# 构建镜像
docker-compose -f docker-compose.prod.yml build
# 启动容器
docker-compose -f docker-compose.prod.yml up -d
# 查看状态
docker-compose -f docker-compose.prod.yml ps
# 查看日志
docker-compose -f docker-compose.prod.yml logs -f
```
#### 5.4 初始化 REDCap 数据库
**方式1使用安装向导推荐**
1. 访问 http://39.105.153.58/install.php
2. 按照向导完成安装
3. 创建管理员账户
**方式2导入 SQL 文件**
```bash
# 如果有现成的 redcap_install.sql
mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \
-u redcap_user -p redcap_prod < redcap_install.sql
```
---
### 阶段6验证部署
#### 6.1 访问测试
| 测试项 | URL | 预期结果 |
|--------|-----|---------|
| 首页 | http://39.105.153.58/ | 显示REDCap登录页 |
| 安装向导 | http://39.105.153.58/install.php | 显示安装页面 |
| 控制中心 | http://39.105.153.58/ControlCenter/ | 需登录后访问 |
#### 6.2 功能验证清单
- [ ] 页面样式正常无404错误
- [ ] 可以成功登录
- [ ] 可以创建项目
- [ ] 可以创建表单
- [ ] 数据可以正常保存
- [ ] API 可以正常调用
---
## 🔒 安全加固(重要!)
### 7.1 修改 REDCap Base URL
登录后在 Control Center 修改:
```
Configuration > General Configuration > REDCap base URL
设置为: http://39.105.153.58
(或您的域名: https://redcap.yourdomain.com
```
### 7.2 配置 HTTPS强烈建议
**方式1使用阿里云 SSL 证书**
1. 申请免费 SSL 证书(阿里云控制台)
2. 下载证书文件
3. 配置 Nginx 反向代理或修改 Apache 配置
**方式2使用 Let's Encrypt**
```bash
# 安装 Certbot
sudo yum install -y certbot
# 获取证书(需要域名指向此服务器)
sudo certbot certonly --standalone -d redcap.yourdomain.com
```
### 7.3 定期备份
```bash
# 创建备份脚本
cat > /opt/redcap/backup.sh << 'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR=/opt/redcap/backups
mkdir -p $BACKUP_DIR
# 备份数据库
mysqldump -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \
-u redcap_user -p'YOUR_PASSWORD' \
redcap_prod > $BACKUP_DIR/redcap_db_$DATE.sql
# 备份 edocs
docker cp redcap-prod:/var/www/html/redcap/edocs $BACKUP_DIR/edocs_$DATE
# 保留最近7天
find $BACKUP_DIR -mtime +7 -delete
echo "Backup completed: $DATE"
EOF
chmod +x /opt/redcap/backup.sh
# 添加定时任务每天凌晨2点
echo "0 2 * * * /opt/redcap/backup.sh" | crontab -
```
---
## 📋 部署检查清单
### 部署前
- [ ] ECS 服务器已启动
- [ ] RDS MySQL 已启动
- [ ] RDS 白名单已添加 ECS 私网 IP
- [ ] 安全组已配置 80/443 端口
- [ ] REDCap 源码已上传
- [ ] database.php 已配置正确的 RDS 连接信息
- [ ] Salt 值已设置并记录(永不可变!)
### 部署后
- [ ] 容器状态正常docker-compose ps
- [ ] 可以访问 http://39.105.153.58/
- [ ] 页面样式正常
- [ ] 可以成功登录
- [ ] 可以创建项目并保存数据
- [ ] 备份脚本已配置
- [ ] 可选HTTPS 已配置
---
## 🛠️ 常用运维命令
```bash
# 进入部署目录
cd /opt/redcap
# 查看容器状态
docker-compose -f docker-compose.prod.yml ps
# 查看日志
docker-compose -f docker-compose.prod.yml logs -f
# 重启服务
docker-compose -f docker-compose.prod.yml restart
# 停止服务
docker-compose -f docker-compose.prod.yml stop
# 启动服务
docker-compose -f docker-compose.prod.yml start
# 重建容器(代码更新后)
docker-compose -f docker-compose.prod.yml up -d --build
# 进入容器
docker exec -it redcap-prod bash
# 查看磁盘使用
docker system df
```
---
## ⚠️ 重要注意事项
### Salt 值
```
⚠️ Salt 值一旦设置,永远不可更改!
用于数据去标识化哈希,更改将导致所有去标识化数据失效。
请务必记录并安全保存。
```
### 密码安全
- 数据库密码建议 32+ 字符
- 定期更换管理员密码
- 不要在代码中硬编码密码
### 数据备份
- 每日自动备份数据库
- edocs 目录包含上传文件,需备份
- 备份文件建议同步到 OSS
---
## 📚 相关文档
- [Docker部署操作手册](./10-REDCap_Docker部署操作手册.md)
- [部署问题排查手册](./13-部署问题排查手册.md)
- [REDCap API使用指南](../03-API对接与开发/30-REDCap_API使用指南.md)
---
## 📝 更新记录
| 日期 | 版本 | 更新内容 |
|------|------|---------|
| 2026-02-02 | v1.0 | 初始版本,基于 ECS + RDS 架构 |
---
**文档维护:** AI Clinical Research 开发团队
**有问题?** 查看 [部署问题排查手册](./13-部署问题排查手册.md)

View File

@@ -0,0 +1,321 @@
# REDCap 生产环境部署信息记录
**创建日期:** 2026-02-02
**最后更新:** 2026-02-02
**状态:** ✅ 部署成功运行中HTTPS + 域名已配置)
**⚠️ 机密文档:** 请妥善保管,不要提交到公开代码仓库
---
## 🌐 访问地址
| 服务 | 地址 | 备注 |
|------|------|------|
| **REDCap 主页** | https://redcap.xunzhengyixue.com/ | ✅ 生产环境(推荐) |
| **REDCap 控制中心** | https://redcap.xunzhengyixue.com/ControlCenter/ | 管理员入口 |
| **REDCap API** | https://redcap.xunzhengyixue.com/api/ | API 接口 |
| **备用地址IP** | http://39.105.153.58/ | 会重定向到 HTTPS |
---
## 🖥️ ECS 服务器信息
| 项目 | 值 |
|------|-----|
| **实例名称** | launch-advisor-20260108 |
| **实例ID** | i-2ze51hziwjg23m2u1fg4 |
| **公网IP** | `39.105.153.58` |
| **私网IP** | `172.17.173.82` |
| **规格** | ecs.u2a-c1m2.large (2核 4GB) |
| **操作系统** | Alibaba Cloud Linux 3.2104 LTS |
| **可用区** | 华北2北京F |
| **到期时间** | 2027-01-09 |
| **VPC** | vpc-2ze055cptkew9c38w4r06 |
### SSH 登录信息
```bash
ssh root@39.105.153.58
```
| 项目 | 值 |
|------|-----|
| **用户名** | root |
| **密码** | `Xilu,881009` |
---
## 🗄️ RDS MySQL 数据库信息
| 项目 | 值 |
|------|-----|
| **实例ID** | rm-2ze9587199003517c |
| **数据库类型** | MySQL 8.0 |
| **规格** | mysql.n2e.medium.1 (2核 4GB) |
| **内网地址** | `rm-2ze9587199003517c.mysql.rds.aliyuncs.com` |
| **端口** | 3306 |
| **可用区** | 华北2北京F |
| **到期时间** | 2027-01-09 |
### REDCap 数据库
| 项目 | 值 |
|------|-----|
| **数据库名** | `redcap_prod` |
| **字符集** | utf8mb4 |
| **用户名** | `redcap_user` |
| **密码** | `Xilu@881009` |
### 数据库连接命令
```bash
mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com -u redcap_user -p'Xilu@881009' redcap_prod
```
---
## 👤 REDCap 管理员账户
| 项目 | 值 |
|------|-----|
| **用户名** | `admin` |
| **密码** | `Xilu,881009` |
| **权限** | 超级管理员 |
---
## 🔐 关键安全信息
### Salt 值(⚠️ 永不可变!)
```
redcap_prod_salt_2026_xilu_medical_v1_never_change
```
> **警告**Salt 值用于数据去标识化哈希,一旦设置**永远不能更改**
> 更改将导致所有去标识化数据失效,请务必备份保存。
### database.php 配置文件位置
```
ECS 路径: /opt/redcap/config/database.php
容器内路径: /var/www/html/redcap/database.php
```
---
## 🐳 Docker 部署信息
### 文件路径
| 文件/目录 | 路径 |
|----------|------|
| **部署根目录** | `/opt/redcap/` |
| **REDCap 源码** | `/opt/redcap/redcap15.8.0/redcap/` |
| **Docker Compose 文件** | `/opt/redcap/docker-compose.prod.yml` |
| **Dockerfile** | `/opt/redcap/Dockerfile.redcap` |
| **database.php** | `/opt/redcap/config/database.php` |
| **Apache 配置** | `/opt/redcap/config/apache/redcap.conf` |
| **PHP 配置** | `/opt/redcap/config/php/php.ini` |
| **日志目录** | `/opt/redcap/logs/` |
### Docker 信息
| 项目 | 值 |
|------|-----|
| **容器名称** | redcap-prod |
| **镜像名称** | redcap-redcap-web |
| **Docker 版本** | 26.1.3 |
| **Docker Compose 版本** | v2.27.0 |
### Docker 数据卷
| 卷名 | 用途 | 备注 |
|------|------|------|
| redcap-edocs-prod | 上传文件 | **重要!需定期备份** |
| redcap-modules-prod | External Modules | 可选备份 |
| redcap-temp-prod | 临时文件 | 可定期清理 |
### 常用 Docker 命令
```bash
# 进入部署目录
cd /opt/redcap
# 查看容器状态
docker compose -f docker-compose.prod.yml ps
# 查看日志
docker logs redcap-prod --tail 100
# 重启服务
docker compose -f docker-compose.prod.yml restart
# 停止服务
docker compose -f docker-compose.prod.yml stop
# 启动服务
docker compose -f docker-compose.prod.yml start
# 进入容器
docker exec -it redcap-prod bash
```
---
## 🔧 Docker 镜像加速器配置
配置文件:`/etc/docker/daemon.json`
```json
{
"registry-mirrors": [
"https://docker.1panel.live",
"https://dockerpull.org",
"https://docker.rainbond.cc",
"https://docker.m.daocloud.io"
]
}
```
---
## 🛡️ 安全组配置
| 规则 | 协议 | 端口 | 授权对象 |
|------|------|------|---------|
| 入方向 | ALL | 全部 | 0.0.0.0/0 |
> **安全建议**:生产环境应限制 SSH 端口22只允许特定 IP 访问
---
## 🔒 HTTPS / SSL 配置
### 域名信息
| 项目 | 值 |
|------|-----|
| **域名** | `redcap.xunzhengyixue.com` |
| **DNS 解析** | A 记录 → `39.105.153.58` |
| **SSL 证书** | 阿里云免费证书DV |
| **证书有效期** | 1 年(需定期续期) |
### Nginx 反向代理
| 项目 | 值 |
|------|-----|
| **Nginx 版本** | 系统默认 |
| **配置文件** | `/etc/nginx/conf.d/redcap.conf` |
| **SSL 证书路径** | `/etc/nginx/ssl/redcap.xunzhengyixue.com.pem` |
| **SSL 私钥路径** | `/etc/nginx/ssl/redcap.xunzhengyixue.com.key` |
| **代理目标** | `http://127.0.0.1:8080` |
### 架构说明
```
用户访问 https://redcap.xunzhengyixue.com
Nginx (443/80) ← SSL 终止
Docker 容器 (8080) ← REDCap Apache
RDS MySQL (3306) ← 数据库
```
### Nginx 常用命令
```bash
# 检查配置
nginx -t
# 重启 Nginx
systemctl restart nginx
# 查看状态
systemctl status nginx
# 查看日志
tail -f /var/log/nginx/error.log
```
---
## 📦 软件版本
| 软件 | 版本 |
|------|------|
| REDCap | 15.8.0 |
| PHP | 8.1.x |
| Apache | 2.4.65 |
| MySQL | 8.0 (RDS) |
| Nginx | 系统默认 |
| Docker | 26.1.3 |
| Docker Compose | v2.27.0 |
| 操作系统 | Alibaba Cloud Linux 3.2104 |
---
## 💾 备份策略
### 数据库备份命令
```bash
# 手动备份
mysqldump -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \
-u redcap_user -p'Xilu@881009' \
redcap_prod > /opt/redcap/backups/redcap_db_$(date +%Y%m%d).sql
# 备份 edocs上传文件
docker cp redcap-prod:/var/www/html/redcap/edocs /opt/redcap/backups/edocs_$(date +%Y%m%d)
```
### 建议备份频率
| 数据类型 | 频率 | 保留时间 |
|---------|------|---------|
| 数据库 | 每日 | 30 天 |
| edocs 文件 | 每周 | 90 天 |
| 配置文件 | 每次修改后 | 永久 |
---
## 📋 部署时间线
| 日期 | 事件 |
|------|------|
| 2026-02-02 | ECS 服务器初始化,安装 Docker CE 26.1.3 |
| 2026-02-02 | 配置 Docker 镜像加速器(国内源) |
| 2026-02-02 | RDS MySQL 配置,创建数据库 redcap_prod 和用户 |
| 2026-02-02 | REDCap 15.8.0 源码和配置文件上传 |
| 2026-02-02 | Docker 容器构建和启动 |
| 2026-02-02 | 执行 redcap_install.sql 初始化数据库表 |
| 2026-02-02 | ✅ REDCap 生产环境部署完成HTTP |
| 2026-02-02 | 配置域名 redcap.xunzhengyixue.com DNS 解析 |
| 2026-02-02 | 申请并配置阿里云 SSL 证书 |
| 2026-02-02 | 安装 Nginx 反向代理,配置 HTTPS |
| 2026-02-02 | ✅ HTTPS + 域名配置完成 |
---
## ⚠️ 重要提醒
1. **Salt 值永不可变** - 更改将导致数据损坏
2. **定期备份数据库** - 防止数据丢失
3. **定期更新密码** - 增强安全性
4. **监控服务器状态** - 及时发现问题
5. **不要将此文档提交到公开仓库** - 包含敏感信息
---
## 📞 技术支持
- REDCap 官方文档https://projectredcap.org/
- 部署操作手册:[10-REDCap_Docker部署操作手册.md](./10-REDCap_Docker部署操作手册.md)
- ECS 部署方案:[14-REDCap_ECS生产环境部署方案.md](./14-REDCap_ECS生产环境部署方案.md)
- 问题排查手册:[13-部署问题排查手册.md](./13-部署问题排查手册.md)
---
**文档版本**v1.0
**创建者**AI Clinical Research 开发团队

View File

@@ -1035,4 +1035,3 @@
font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
font-size: 0.9em;
}