diff --git a/Redcap 问题原因排查.md b/Redcap 问题原因排查.md new file mode 100644 index 00000000..4ffdf173 --- /dev/null +++ b/Redcap 问题原因排查.md @@ -0,0 +1,59 @@ +# **REDCap ERR\_CONTENT\_DECODING\_FAILED 错误排查与修复指南** + +如果在浏览器访问 REDCap 时遇到 net::ERR\_CONTENT\_DECODING\_FAILED 200 (OK),说明数据包在传输过程中被“弄脏”了。以下是按优先级排序的 4 种解决方案: + +## **1\. 禁用 PHP 的 zlib 输出压缩 (最常见原因)** + +REDCap 内部有时会尝试自己控制输出压缩,如果你的 php.ini 里也开启了 zlib.output\_compression,两者冲突就会导致解码失败。 + +**操作步骤:** + +1. 找到你挂载到 Docker 容器里的 php.ini 文件。 +2. 搜索 zlib.output\_compression。 +3. 将其设置为 Off: + zlib.output\_compression \= Off + +4. **重启 Docker 容器**:docker-compose restart redcap-web。 + +## **2\. 检查并清理 PHP 文件的 BOM 头** + +如果你编辑过 database.php 或 config.php,并使用了 Windows 记事本,可能会在文件开头插入一个不可见的 **UTF-8 BOM** 字符。这个字符会抢在 Gzip 报文头之前发送,导致浏览器解压失败。 + +**操作步骤:** + +1. 使用 VS Code 或 Notepad++ 打开 database.php。 +2. 检查右下角的编码格式。如果是 UTF-8 with BOM,请将其更改为 **UTF-8** (无 BOM)。 +3. 确保 \ **文档版本:** v2.0 +> **创建日期:** 2026-01-01 +> **最后更新:** 2026-01-01(根据ECS决议报告修订) +> **文档目的:** 指导IIT Manager Agent项目的REDCap Docker环境搭建(开发/生产架构一致) +> **阅读时间:** 25分钟 +> **重要性:** ⭐⭐⭐⭐⭐ **Day 2开发前必读** +> **预计部署时间:** 1.5小时 +> **架构决策依据:** [REDCap生产环境部署:ECS vs SAE深度决议报告](./REDCap%20生产环境部署:ECS%20vs%20SAE%20深度决议报告.md) + +--- + +## 📋 文档说明 + +### 核心理念:**本地开发即生产环境** 🎯 + +本文档基于IIT Manager Agent项目的**混合架构决策**,采用Docker容器化部署REDCap,实现: +- ✅ **开发环境 = 测试环境 = 生产环境**(无环境漂移) +- ✅ **Docker配置可直接用于阿里云ECS生产部署** +- ✅ **Docker配置可直接用于医院内网私有化部署** +- ✅ **2人团队可维护的简单架构** + +### 架构定位 + +```yaml +数据平面 (Data Layer) - REDCap部署策略: +├─ 本地开发:Docker Compose (Windows/Mac) +├─ 阿里云测试/生产:ECS + Docker + RDS MySQL +└─ 医院私有化:服务器 + Docker + 本地MySQL + +控制平面 (AI Agent Layer) - 部署策略: +├─ Node.js后端:阿里云SAE (Serverless) +├─ Python微服务:阿里云SAE +└─ React前端:阿里云SAE + +为什么REDCap用ECS而不是SAE? +❌ REDCap有三个"致命特性"不适合Serverless: + 1. Cron依赖(心跳任务) + 2. Session粘滞(本地会话) + 3. POSIX文件系统依赖(本地存储) + +详见:REDCap生产环境部署:ECS vs SAE深度决议报告.md +``` + +### 适用场景 + +**本地开发环境**: +- ✅ REDCap API Adapter开发与测试 +- ✅ External Module开发与调试 +- ✅ IIT试验项目原型验证 +- ✅ API Token测试和数据格式验证 + +**生产环境**(相同Docker配置 + 额外配置): +- ✅ 阿里云ECS生产部署(+ RDS + OSS + SLB) +- ✅ 医院内网私有化部署(+ SSL + 备份) +- ✅ 多院区标准化交付 + +--- + +## 🎯 一、核心架构设计 + +### 1.1 容器架构(开发/生产一致) + +#### 生产级核心容器(必需) + +``` +REDCap Docker环境(开发/生产通用) +├─ 容器1: MySQL 8.0 数据库 【redcap-db】 +│ ├─ 本地开发:Docker容器 +│ └─ 生产环境:阿里云RDS MySQL(推荐)或Docker容器 +│ +└─ 容器2: Apache + PHP 8.1 + REDCap 【redcap-web】 + ├─ 包含Cron定时任务 + ├─ 包含External Modules + └─ 本地存储(edocs/、modules/、temp/) + +网络:redcap-network(bridge模式) +存储:Docker命名卷(持久化数据) +``` + +#### 开发辅助容器(仅开发环境,生产禁用) + +``` +⚠️ 以下容器仅用于本地开发调试,生产环境出于安全考虑应禁用: + +容器3: phpMyAdmin(可选) 【phpmyadmin】 +├─ 用途:数据库可视化管理、调试 +├─ 端口:8081 +└─ 生产环境:❌ 不部署(安全风险) + +说明: +生产环境数据库管理应通过: +✅ 阿里云RDS控制台 +✅ MySQL命令行(SSH连接) +✅ 受限的DMS数据管理服务 +``` + +### 1.2 架构优势 + +``` +✅ 开发/生产环境一致(消除"在我机器上能跑"问题) +✅ MySQL在Docker内,无需本机安装(开发环境) +✅ 可无缝切换到RDS MySQL(生产环境) +✅ 所有依赖隔离,不污染主机环境 +✅ 一键启动/停止,2人团队可维护 +✅ 环境可重复构建(容器化标准交付) +✅ 易于销毁重建(测试友好) +✅ 数据持久化(Docker卷 或 RDS) +✅ 支持多版本并存(不同端口) +✅ 直接可用于医院内网部署(离线交付) +``` + +### 1.3 端口分配 + +| 服务 | 容器端口 | 主机端口 | 访问地址 | 生产环境 | +|------|---------|---------|---------|---------| +| REDCap Web | 80 | 8080 | http://localhost:8080 | ✅ 部署(端口80) | +| MySQL | 3306 | 3306 | localhost:3306 | ⚠️ 或使用RDS | +| phpMyAdmin | 80 | 8081 | http://localhost:8081 | ❌ 禁用 | + +**生产环境端口调整**: +- REDCap Web:使用标准80/443端口(通过SLB) +- MySQL:如使用RDS,无需暴露端口(内网连接) +- phpMyAdmin:不部署 + +--- + +## 🗂️ 二、文件结构规划 + +### 2.1 项目目录结构 + +``` +AIclinicalresearch/ +├─ redcap15.8.0/ # ✅ 已有REDCap源码 +│ └─ redcap/ # REDCap核心文件 +│ +├─ redcap-docker-dev/ # 🆕 Docker部署目录(需创建) +│ ├─ docker-compose.yml # Docker编排配置(核心) +│ ├─ Dockerfile.redcap # REDCap容器镜像定义 +│ ├─ .env # 环境变量(数据库密码等) +│ │ +│ ├─ config/ # 配置文件目录 +│ │ ├─ apache/ +│ │ │ └─ redcap.conf # Apache虚拟主机配置 +│ │ ├─ php/ +│ │ │ └─ php.ini # PHP配置 +│ │ └─ database.php # REDCap数据库连接配置 +│ │ +│ ├─ scripts/ # 自动化脚本 +│ │ ├─ setup-redcap.ps1 # 🔧 一键部署脚本(PowerShell) +│ │ ├─ start-redcap.ps1 # 🚀 启动脚本 +│ │ ├─ stop-redcap.ps1 # ⏹️ 停止脚本 +│ │ ├─ logs-redcap.ps1 # 📝 查看日志 +│ │ └─ clean-redcap.ps1 # 🗑️ 清理环境 +│ │ +│ └─ README.md # 部署文档 +``` + +### 2.2 目录说明 + +| 目录/文件 | 用途 | 开发环境 | 生产环境 | +|----------|------|---------|---------| +| `docker-compose.yml` | 定义多容器应用 | ✅ 必需 | ✅ 必需(需调整) | +| `Dockerfile.redcap` | 自定义REDCap镜像 | ✅ 必需 | ✅ 必需 | +| `.env` | 敏感信息(密码) | ✅ 必需 | ✅ 必需(强密码) | +| `config/apache/` | Web服务器配置 | ✅ 必需 | ✅ 必需(+SSL) | +| `config/php/` | PHP运行时配置 | ✅ 必需 | ✅ 必需 | +| `config/database.php` | REDCap数据库连接 | ✅ 必需 | ✅ 必需(RDS连接) | +| `scripts/` | 运维脚本 | ⭐ 推荐 | ✅ 必需 | + +**生产环境额外需要**: +- SSL证书文件(Let's Encrypt或商业证书) +- 备份脚本(数据库 + 文件) +- 监控配置(CloudMonitor Agent) +- 日志轮转配置 + +--- + +## 🔧 三、关键配置说明 + +### 3.1 MySQL配置(容器内) + +#### 3.1.1 基本配置 + +```yaml +# docker-compose.yml - MySQL服务 +services: + redcap-db: + image: mysql:8.0 + container_name: redcap-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + volumes: + - redcap-db-data:/var/lib/mysql # 数据持久化 + ports: + - "3306:3306" + networks: + - redcap-network + command: --default-authentication-plugin=mysql_native_password +``` + +#### 3.1.2 环境变量(.env文件) + +```bash +# 数据库配置(开发环境) +MYSQL_ROOT_PASSWORD=redcap_root_123 +MYSQL_DATABASE=redcap +MYSQL_USER=redcap_user +MYSQL_PASSWORD=redcap_pass_456 + +# ⚠️ 警告:这些是开发环境密码! +# 生产环境必须使用强密码! +``` + +#### 3.1.3 认证插件说明 + +```bash +# 为什么使用 mysql_native_password? +# REDCap 15.8.0兼容性要求 +# 如果使用MySQL 8.0默认的caching_sha2_password会导致连接失败 +``` + +--- + +### 3.2 PHP + Apache配置 + +#### 3.2.1 PHP配置(php.ini) + +```ini +# config/php/php.ini + +# ========== 文件上传(REDCap必需)========== +upload_max_filesize = 32M # REDCap文件上传限制 +post_max_size = 32M # 表单提交大小 +max_file_uploads = 20 # 同时上传文件数 + +# ========== 执行时间(数据导出需要)========== +max_execution_time = 300 # 5分钟(大数据导出) +max_input_time = 300 # 输入解析时间 + +# ========== 内存(REDCap最低要求)========== +memory_limit = 256M # REDCap推荐256MB + +# ========== 时区(重要!)========== +date.timezone = Asia/Shanghai # 北京时间 + +# ========== 错误报告(开发环境)========== +display_errors = On # 开发环境显示错误 +error_reporting = E_ALL # 报告所有错误 + +# ========== Session配置 ========== +session.gc_maxlifetime = 3600 # Session过期时间(1小时) +session.cookie_lifetime = 0 # Cookie浏览器关闭时过期 +``` + +#### 3.2.2 PHP扩展(必需) + +```dockerfile +# Dockerfile.redcap 中安装扩展 + +# 核心扩展(REDCap必需) +RUN docker-php-ext-install \ + mysqli # MySQL连接(必需) + pdo_mysql # PDO支持(必需) + gd # 图片处理(验证码、图表) + zip # 数据导出压缩 + mbstring # 多字节字符串(UTF-8) + curl # API调用 + soap # Web Service集成(可选) + ldap # LDAP认证(可选) + +# Apache模块 +RUN a2enmod rewrite ssl headers +``` + +#### 3.2.3 Apache配置(redcap.conf) + +```apache +# config/apache/redcap.conf + + + ServerName localhost + DocumentRoot /var/www/html/redcap + + + Options -Indexes +FollowSymLinks + AllowOverride All + Require all granted + + # 防止目录遍历 + Options -Indexes + + # 允许.htaccess + AllowOverride All + + + # 日志配置 + ErrorLog ${APACHE_LOG_DIR}/redcap-error.log + CustomLog ${APACHE_LOG_DIR}/redcap-access.log combined + + # 安全头(开发环境可选) + # Header always set X-Frame-Options "SAMEORIGIN" + # Header always set X-Content-Type-Options "nosniff" + +``` + +--- + +### 3.3 REDCap database.php配置 + +#### 3.3.1 数据库连接配置 + +```php + +``` + +#### 3.3.2 Salt值说明 + +``` +什么是Salt? +- 用于REDCap数据导出时的去标识化 +- 影响哈希数据的生成 +- 一旦设置后不可更改(会导致历史数据无法解密) + +开发环境建议: +- 使用固定的Salt值(便于多次重建环境) +- 包含项目标识(如'iit_dev_salt_2026') +- 至少8个字符,建议20+字符 + +生产环境要求: +- 使用强随机Salt(32+字符) +- 包含大小写字母、数字、特殊字符 +- 妥善备份(丢失会导致数据无法解密) +``` + +--- + +## 📧 四、邮件服务配置策略 + +### 4.1 三种配置方案对比 + +| 方案 | 复杂度 | 功能 | 推荐场景 | +|------|--------|------|---------| +| **方案A:跳过配置** | ⭐ 最简单 | 无邮件功能 | ✅ Day 2-8 API开发 | +| **方案B:MailHog** | ⭐⭐ 简单 | 本地邮件拦截 | Day 9-10 邮件测试 | +| **方案C:真实SMTP** | ⭐⭐⭐ 复杂 | 真实邮件发送 | 后期集成测试 | + +### 4.2 方案A:跳过配置(推荐用于Day 2-8) + +```yaml +优势: +✅ 配置最简单 +✅ 启动最快 +✅ 不影响API开发 +✅ REDCap可正常运行 + +限制: +❌ 无法发送调查邀请 +❌ 无法发送密码重置邮件 +❌ 无法发送系统通知 + +实施方法: +1. REDCap安装时跳过SMTP配置步骤 +2. 控制中心 → Email & Notification → 留空 +3. 直接进行API开发 + +适用于: +✅ REDCap API Adapter开发 +✅ External Module开发(不涉及邮件) +✅ 数据导入导出测试 +``` + +### 4.3 方案B:MailHog(本地邮件测试) + +```yaml +# docker-compose.yml 添加MailHog服务 +services: + mailhog: + image: mailhog/mailhog + container_name: redcap-mailhog + ports: + - "1025:1025" # SMTP端口 + - "8025:8025" # Web UI端口 + networks: + - redcap-network + +# REDCap SMTP配置 +SMTP Host: mailhog +SMTP Port: 1025 +SMTP Auth: 无需认证 + +# 访问Web界面查看邮件 +http://localhost:8025 +``` + +**使用场景**:测试调查邀请、密码重置等邮件功能 + +### 4.4 方案C:真实SMTP(Gmail/Outlook) + +```yaml +# REDCap控制中心配置 + +# Gmail示例 +SMTP Host: smtp.gmail.com +SMTP Port: 587 +SMTP Auth: TLS +Username: your-email@gmail.com +Password: app-specific-password # 不是Gmail密码! + +# 限制 +- Gmail:每天100封(免费账户) +- Outlook:每天300封 +- 需要开启"不够安全的应用访问"或使用应用专用密码 +``` + +**推荐策略**: +- **Day 2-8**:使用方案A(跳过) +- **Day 9-10**:如需测试邮件,临时切换到方案B +- **生产环境**:使用企业SMTP或云服务(SendGrid、阿里云DirectMail) + +--- + +## 🌐 五、本地 vs 云端部署 + +### 5.1 Docker镜像可移植性分析 + +#### 本地Docker → 阿里云ECS:是否可以? + +``` +答案:可以,但不推荐直接迁移! + +可以这样做: +1. 导出Docker镜像 + docker save redcap-local:1.0 -o redcap.tar +2. 上传到ECS + scp redcap.tar user@ecs-ip:/tmp/ +3. 在ECS导入 + docker load -i /tmp/redcap.tar +4. 运行容器 + docker run -d -p 80:80 redcap-local:1.0 + +但为什么不推荐? +❌ 性能:Docker多一层虚拟化,损失10-20%性能 +❌ 稳定性:容器层增加复杂度和故障点 +❌ 运维:医疗系统需要最大可控性 +❌ 备份:容器数据备份更复杂 +❌ 监控:直接部署更易于监控和调试 +``` + +### 5.2 推荐的云端部署策略 + +``` +本地开发(Docker)→ 云端生产(标准部署) + +阶段1:本地Docker开发(当前) +- 目的:API Adapter开发、External Module开发 +- 环境:Windows + Docker Desktop +- 数据:测试数据(可随时销毁) + +阶段2:ECS标准部署(未来) +- 目的:生产环境、真实医疗数据 +- 环境:Ubuntu 22.04 + LAMP +- 数据:RDS MySQL(高可用)+ OSS存储 + +迁移路径: +1. 在本地Docker完成External Module开发 +2. 验证API Adapter功能 +3. 在ECS上标准安装REDCap(LAMP) +4. 复制External Module代码到ECS +5. 配置生产级数据库和SMTP +6. 配置SSL证书和域名 +``` + +### 5.3 环境对比表 + +| 对比项 | 本地Docker | 阿里云ECS(标准部署) | +|--------|-----------|---------------------| +| **部署方式** | Docker Compose | LAMP手动安装 | +| **访问地址** | localhost:8080 | https://redcap.domain.com | +| **数据库** | Docker容器 | RDS MySQL(推荐)或本地 | +| **存储** | Docker卷 | OSS或本地磁盘 | +| **邮件** | 跳过或MailHog | 阿里云DirectMail/SendGrid | +| **SSL** | 不需要 | Let's Encrypt证书 | +| **性能** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **稳定性** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | +| **成本** | $0 | $50-200/月 | +| **适用场景** | 开发测试 | 生产环境 | + +--- + +## 🔑 六、关键注意事项 + +### 6.1 坑点1:文件权限问题 ⚠️ + +#### 症状 +```bash +安装时提示: +"Unable to write to /var/www/html/edocs directory" +"Unable to write to /var/www/html/temp directory" +``` + +#### 原因 +``` +Apache运行用户(www-data)对目录无写权限 +Docker容器内文件权限与主机不同步 +``` + +#### 解决方案 +```bash +# 方法1:启动后手动修复(推荐) +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/edocs +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/temp +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/modules + +# 方法2:在Dockerfile中预先配置 +RUN mkdir -p /var/www/html/edocs /var/www/html/temp /var/www/html/modules && \ + chown -R www-data:www-data /var/www/html +``` + +#### 预防措施 +```bash +# 检查权限 +docker exec -it redcap-web ls -la /var/www/html/ + +# 应该看到: +drwxr-xr-x www-data www-data edocs +drwxr-xr-x www-data www-data temp +drwxr-xr-x www-data www-data modules +``` + +--- + +### 6.2 坑点2:数据库连接失败 ⚠️ + +#### 症状 +```bash +安装页面提示: +"Cannot connect to database" +"Access denied for user 'redcap_user'@'redcap-web.redcap-network'" +``` + +#### 原因 +``` +原因1: MySQL容器未完全启动 +原因2: database.php配置错误(hostname) +原因3: 认证插件不兼容(caching_sha2_password) +``` + +#### 解决方案 + +**问题1:MySQL未就绪** +```bash +# 查看MySQL日志,等待"ready for connections" +docker-compose logs redcap-db | grep "ready for connections" + +# 输出示例: +# 2026-01-01 10:00:00 [Server] /usr/sbin/mysqld: ready for connections. + +# 建议等待30秒后再访问install.php +``` + +**问题2:hostname配置错误** +```php +// ❌ 错误配置 +$hostname = 'localhost'; // 容器内localhost不是MySQL +$hostname = '127.0.0.1'; // 同上 +$hostname = 'redcap-mysql'; // 容器名,但应使用服务名 + +// ✅ 正确配置 +$hostname = 'redcap-db'; // Docker Compose服务名 +``` + +**问题3:认证插件** +```bash +# 确保docker-compose.yml中包含: +command: --default-authentication-plugin=mysql_native_password + +# 或在MySQL容器内手动修改用户 +docker exec -it redcap-mysql mysql -uroot -p +ALTER USER 'redcap_user'@'%' IDENTIFIED WITH mysql_native_password BY 'redcap_pass_456'; +FLUSH PRIVILEGES; +``` + +--- + +### 6.3 坑点3:PHP扩展缺失 ⚠️ + +#### 症状 +```bash +install.php检查页面提示: +"The GD extension is not loaded" +"The ZIP extension is not loaded" +"The MySQLi extension is not loaded" +``` + +#### 原因 +``` +php:8.1-apache基础镜像只包含核心扩展 +REDCap需要额外安装10+个扩展 +``` + +#### 解决方案 + +**Dockerfile中预装(推荐)** +```dockerfile +FROM php:8.1-apache + +# 安装系统依赖 +RUN apt-get update && apt-get install -y \ + libpng-dev \ + libjpeg-dev \ + libfreetype6-dev \ + libzip-dev \ + libldap2-dev \ + && rm -rf /var/lib/apt/lists/* + +# 安装PHP扩展 +RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \ + docker-php-ext-install -j$(nproc) \ + mysqli \ + pdo_mysql \ + gd \ + zip \ + mbstring \ + curl \ + soap \ + ldap + +# 启用Apache模块 +RUN a2enmod rewrite ssl headers +``` + +**验证安装** +```bash +# 进入容器检查 +docker exec -it redcap-web php -m | grep -E '(mysqli|gd|zip|mbstring)' + +# 应该看到: +gd +mbstring +mysqli +zip +``` + +--- + +### 6.4 坑点4:Windows路径映射 ⚠️ + +#### 症状 +```bash +容器启动失败或无法访问文件 +Error: "no such file or directory" +``` + +#### 原因 +``` +Windows路径格式与Linux不兼容 +反斜杠(\)与正斜杠(/)冲突 +绝对路径在Docker Desktop中可能有问题 +``` + +#### 解决方案 + +**使用相对路径(推荐)** +```yaml +# ✅ 正确:相对路径 +volumes: + - ../redcap15.8.0/redcap:/var/www/html/redcap + - ./config/apache/redcap.conf:/etc/apache2/sites-available/000-default.conf + +# ❌ 错误:Windows绝对路径 +volumes: + - D:\MyCursor\AIclinicalresearch\redcap15.8.0\redcap:/var/www/html/redcap + +# 🟡 可能可以:WSL路径(如果使用WSL2后端) +volumes: + - /mnt/d/MyCursor/AIclinicalresearch/redcap15.8.0/redcap:/var/www/html/redcap +``` + +**PowerShell中转换路径** +```powershell +# 获取当前目录的相对路径 +$currentDir = Get-Location +$redcapSource = Join-Path $currentDir.Parent.FullName "redcap15.8.0\redcap" +Write-Host "REDCap Source: $redcapSource" +``` + +--- + +### 6.5 坑点5:端口冲突 ⚠️ + +#### 症状 +```bash +docker-compose up -d 失败 +Error: "Bind for 0.0.0.0:8080 failed: port is already allocated" +``` + +#### 原因 +``` +本机已有服务占用相同端口 +- 8080: 可能有其他Web服务 +- 3306: 可能已安装本地MySQL +- 8081: 可能有其他管理工具 +``` + +#### 解决方案 + +**检查端口占用(Windows)** +```powershell +# 检查8080端口 +netstat -ano | findstr :8080 + +# 输出示例: +# TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 1234 + +# 查看占用进程 +tasklist | findstr 1234 + +# 结束进程(谨慎!) +taskkill /F /PID 1234 +``` + +**修改端口映射** +```yaml +# 如果8080被占用,改用8888 +services: + redcap-web: + ports: + - "8888:80" # 主机8888 → 容器80 + +# 如果3306被占用,改用3307 + redcap-db: + ports: + - "3307:3306" +``` + +**最佳实践** +```bash +# 预先检查所有端口 +netstat -ano | findstr :8080 +netstat -ano | findstr :3306 +netstat -ano | findstr :8081 + +# 如果都空闲,使用默认端口 +# 如果有冲突,提前修改docker-compose.yml +``` + +--- + +### 6.6 坑点6:数据持久化误区 ⚠️ + +#### 症状 +```bash +容器删除后,数据丢失 +docker-compose down 后无法恢复项目 +``` + +#### 原因 +``` +误用了--volumes参数删除了数据卷 +没有理解Docker命名卷的概念 +``` + +#### 正确理解 + +**Docker数据卷类型** +```yaml +# 类型1:命名卷(推荐,开发环境) +volumes: + - redcap-db-data:/var/lib/mysql +# 特点:Docker管理,跨容器持久化,删除容器不影响 + +# 类型2:绑定挂载(不推荐,Windows性能差) +volumes: + - ./mysql-data:/var/lib/mysql +# 特点:主机目录,可见但性能差 + +# 类型3:tmpfs(临时,不持久化) +tmpfs: + - /var/lib/mysql +# 特点:内存存储,容器停止即丢失 +``` + +**安全操作** +```bash +# ✅ 停止容器(保留数据) +docker-compose stop + +# ✅ 停止并删除容器(保留数据) +docker-compose down + +# ⚠️ 删除容器和网络,但保留卷(安全) +docker-compose down --volumes=false + +# ❌ 删除所有(包括数据卷,危险!) +docker-compose down --volumes +docker-compose down -v # 同上 +``` + +**数据备份** +```bash +# 备份MySQL数据卷 +docker run --rm -v redcap-db-data:/data -v $(pwd):/backup \ + ubuntu tar czf /backup/redcap-db-backup.tar.gz /data + +# 恢复数据卷 +docker run --rm -v redcap-db-data:/data -v $(pwd):/backup \ + ubuntu tar xzf /backup/redcap-db-backup.tar.gz -C / +``` + +--- + +## 🚀 七、部署流程(详细步骤) + +### 7.1 阶段1:准备配置文件(15分钟) + +#### 步骤1:创建项目目录 +```powershell +# 进入项目根目录 +cd D:\MyCursor\AIclinicalresearch + +# 创建Docker部署目录 +New-Item -ItemType Directory -Path "redcap-docker-dev" -Force +cd redcap-docker-dev + +# 创建子目录 +New-Item -ItemType Directory -Path "config\apache" -Force +New-Item -ItemType Directory -Path "config\php" -Force +New-Item -ItemType Directory -Path "scripts" -Force +``` + +#### 步骤2:生成配置文件 +```powershell +# 此步骤将由自动化脚本完成,生成: +# - docker-compose.yml +# - Dockerfile.redcap +# - .env +# - config/apache/redcap.conf +# - config/php/php.ini +# - config/database.php +# - scripts/*.ps1 +``` + +#### 步骤3:验证REDCap源码 +```powershell +# 确认源码存在 +Test-Path ..\redcap15.8.0\redcap\install.php + +# 输出:True(表示源码存在) +``` + +--- + +### 7.2 阶段2:启动容器(10分钟) + +#### 步骤1:构建镜像 +```powershell +# 构建自定义REDCap镜像 +docker-compose build + +# 输出示例: +# Building redcap-web... +# Step 1/10 : FROM php:8.1-apache +# ... +# Successfully built abc123def456 +# Successfully tagged redcap-docker-dev_redcap-web:latest +``` + +#### 步骤2:启动所有容器 +```powershell +# 后台启动 +docker-compose up -d + +# 输出示例: +# Creating network "redcap-docker-dev_redcap-network" ... done +# Creating volume "redcap-docker-dev_redcap-db-data" ... done +# Creating redcap-mysql ... done +# Creating redcap-web ... done +# Creating redcap-phpmyadmin ... done +``` + +#### 步骤3:等待MySQL就绪 +```powershell +# 查看MySQL日志 +docker-compose logs redcap-db | Select-String "ready for connections" + +# 等待看到: +# [Server] /usr/sbin/mysqld: ready for connections. + +# 建议等待30秒 +Start-Sleep -Seconds 30 +``` + +#### 步骤4:修复文件权限 +```powershell +# 自动修复权限脚本(已包含在setup-redcap.ps1中) +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/edocs +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/temp +docker exec -it redcap-web chown -R www-data:www-data /var/www/html/modules +``` + +#### 步骤5:验证容器状态 +```powershell +# 检查所有容器运行状态 +docker-compose ps + +# 应该看到: +# Name State Ports +# redcap-mysql Up 0.0.0.0:3306->3306/tcp +# redcap-web Up 0.0.0.0:8080->80/tcp +# redcap-phpmyadmin Up 0.0.0.0:8081->80/tcp +``` + +--- + +### 7.3 阶段3:REDCap安装(30分钟) + +#### 步骤1:访问安装向导 +``` +打开浏览器访问: +http://localhost:8080/install.php +``` + +#### 步骤2:系统要求检查 +``` +REDCap会自动检查: +✅ PHP版本 8.1.x +✅ MySQL连接 +✅ PHP扩展(mysqli, gd, zip, etc.) +✅ 文件权限(edocs, temp可写) + +如果有红叉❌,根据提示修复 +``` + +#### 步骤3:数据库配置 +``` +MySQL Hostname: redcap-db +MySQL Database: redcap +MySQL Username: redcap_user +MySQL Password: redcap_pass_456 +Table Prefix: (留空,使用默认) + +Salt: iit_dev_salt_2026_redcap_v15 +``` + +#### 步骤4:管理员账户 +``` +Username: admin +Password: Admin@123456 # 开发环境密码 +Email: dev@example.com +First Name: Admin +Last Name: User +``` + +#### 步骤5:SMTP配置 +``` +选择:Skip SMTP Configuration(跳过) +原因:Day 2-8不需要邮件功能 +``` + +#### 步骤6:完成安装 +``` +点击 "Complete Installation" +等待数据库表创建(约2-3分钟) +看到 "Installation Complete!" 消息 +``` + +#### 步骤7:首次登录 +``` +访问:http://localhost:8080/ +用户名:admin +密码:Admin@123456 + +✅ 登录成功,看到REDCap主页 +``` + +--- + +### 7.4 阶段4:创建测试项目(30分钟) + +#### 步骤1:新建项目 +``` +1. 点击 "New Project" +2. 项目标题:IIT Test Project +3. 项目目的:Research +4. 模板:Empty Project(从头创建) +5. 点击 "Create Project" +``` + +#### 步骤2:设计数据字典 + +**创建表单1:患者信息(Demographics)** +``` +字段列表: +1. record_id (Record ID) + - 类型:Text Box + - 验证:Integer + - 标识符:Yes + +2. patient_name (患者姓名) + - 类型:Text Box + - 标识符:Yes + +3. age (年龄) + - 类型:Text Box + - 验证:Integer + - 范围:1-120 + +4. gender (性别) + - 类型:Radio Buttons + - 选项:1, 男 | 2, 女 + +5. enrollment_date (入组日期) + - 类型:Text Box + - 验证:Date (Y-M-D) +``` + +**创建表单2:随访记录(Follow-up)** +``` +字段列表: +1. followup_date (随访日期) + - 类型:Text Box + - 验证:Date (Y-M-D) + +2. followup_type (随访类型) + - 类型:Dropdown + - 选项:1, 门诊 | 2, 电话 | 3, 线上 + +3. adverse_event (不良事件) + - 类型:Yes-No + - 默认:No + +4. notes (备注) + - 类型:Notes Box (Paragraph Text) +``` + +#### 步骤3:创建测试数据 +``` +添加5条测试受试者记录: + +Record 1: +- patient_name: 张三 +- age: 45 +- gender: 男 +- enrollment_date: 2025-12-01 + +Record 2: +- patient_name: 李四 +- age: 52 +- gender: 女 +- enrollment_date: 2025-12-05 + +... (省略3条) +``` + +#### 步骤4:启用API访问 +``` +1. 进入项目 +2. 左侧菜单 → Applications → API +3. 点击 "Enable API Access" +4. 勾选 "Export"、"Import" 权限 +5. 点击 "Request API Token" +6. 系统生成Token(自动批准,因为是管理员) +7. 复制Token保存: + 示例:A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6 +``` + +#### 步骤5:测试API调用 +```bash +# PowerShell测试导出数据 +$apiUrl = "http://localhost:8080/api/" +$token = "YOUR_API_TOKEN_HERE" + +$body = @{ + token = $token + content = 'record' + format = 'json' + type = 'flat' +} + +Invoke-RestMethod -Uri $apiUrl -Method Post -Body $body + +# 应该返回JSON数组,包含5条测试数据 +``` + +--- + +### 7.5 阶段5:配置后端环境变量(15分钟) + +#### 步骤1:更新后端.env +```bash +# AIclinicalresearch/backend/.env + +# ========== REDCap配置(新增)========== +REDCAP_API_URL=http://localhost:8080/api/ +REDCAP_API_TOKEN=A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6 +REDCAP_PROJECT_ID=1 + +# 注意:localhost在Docker容器内需要改为host.docker.internal +# 如果后端也在Docker内,应使用容器IP或服务名 +``` + +#### 步骤2:创建API测试脚本 +```typescript +// backend/src/modules/iit-manager/test-redcap-api.ts + +import axios from 'axios'; + +const REDCAP_API_URL = process.env.REDCAP_API_URL || 'http://localhost:8080/api/'; +const REDCAP_API_TOKEN = process.env.REDCAP_API_TOKEN || ''; + +async function testREDCapAPI() { + console.log('🔍 Testing REDCap API Connection...'); + + try { + const response = await axios.post(REDCAP_API_URL, new URLSearchParams({ + token: REDCAP_API_TOKEN, + content: 'record', + format: 'json', + type: 'flat' + })); + + console.log('✅ API Connection Successful!'); + console.log(`📊 Retrieved ${response.data.length} records`); + console.log('Sample Record:', response.data[0]); + } catch (error: any) { + console.error('❌ API Connection Failed:', error.message); + } +} + +testREDCapAPI(); +``` + +#### 步骤3:运行测试 +```powershell +cd D:\MyCursor\AIclinicalresearch\backend +npx ts-node src/modules/iit-manager/test-redcap-api.ts + +# 预期输出: +# 🔍 Testing REDCap API Connection... +# ✅ API Connection Successful! +# 📊 Retrieved 5 records +# Sample Record: { record_id: '1', patient_name: '张三', ... } +``` + +--- + +### 7.6 部署完成验证清单 + +``` +验证项 状态 +───────────────────────────────────────────────── +✅ Docker容器全部运行 [ ] +✅ MySQL数据库可连接 [ ] +✅ REDCap安装成功 [ ] +✅ 管理员账户可登录 [ ] +✅ 测试项目已创建 [ ] +✅ API Token已生成 [ ] +✅ API调用测试通过 [ ] +✅ 后端环境变量已配置 [ ] +✅ phpMyAdmin可访问(可选) [ ] + +全部勾选✅,表示部署成功! +``` + +--- + +## 💡 八、运维管理脚本 + +### 8.1 启动脚本(start-redcap.ps1) + +```powershell +#!/usr/bin/env pwsh +# start-redcap.ps1 - 启动REDCap开发环境 + +Write-Host "🚀 Starting REDCap Development Environment..." -ForegroundColor Cyan + +# 检查Docker是否运行 +$dockerRunning = docker info 2>&1 | Select-String "Server Version" +if (-not $dockerRunning) { + Write-Host "❌ Docker is not running. Please start Docker Desktop." -ForegroundColor Red + exit 1 +} + +# 启动容器 +docker-compose up -d + +# 等待MySQL就绪 +Write-Host "⏳ Waiting for MySQL to be ready..." -ForegroundColor Yellow +Start-Sleep -Seconds 10 + +docker-compose logs redcap-db | Select-String "ready for connections" + +# 显示服务状态 +Write-Host "" +Write-Host "✅ REDCap Environment Started!" -ForegroundColor Green +Write-Host "" +Write-Host "📋 Service URLs:" -ForegroundColor Cyan +Write-Host " REDCap: http://localhost:8080" -ForegroundColor White +Write-Host " phpMyAdmin: http://localhost:8081" -ForegroundColor White +Write-Host "" +Write-Host "📊 Container Status:" -ForegroundColor Cyan +docker-compose ps +``` + +### 8.2 停止脚本(stop-redcap.ps1) + +```powershell +#!/usr/bin/env pwsh +# stop-redcap.ps1 - 停止REDCap开发环境 + +Write-Host "⏹️ Stopping REDCap Development Environment..." -ForegroundColor Yellow + +# 停止容器(保留数据) +docker-compose stop + +Write-Host "✅ REDCap Environment Stopped!" -ForegroundColor Green +Write-Host "" +Write-Host "💡 Data volumes are preserved." -ForegroundColor Cyan +Write-Host " Run 'start-redcap.ps1' to restart." -ForegroundColor Cyan +``` + +### 8.3 查看日志脚本(logs-redcap.ps1) + +```powershell +#!/usr/bin/env pwsh +# logs-redcap.ps1 - 查看REDCap日志 + +param( + [string]$Service = "", + [switch]$Follow +) + +Write-Host "📝 REDCap Container Logs" -ForegroundColor Cyan +Write-Host "" + +if ($Follow) { + # 实时跟踪日志 + if ($Service) { + docker-compose logs -f $Service + } else { + docker-compose logs -f + } +} else { + # 显示最近日志 + if ($Service) { + docker-compose logs --tail=50 $Service + } else { + docker-compose logs --tail=50 + } +} +``` + +### 8.4 清理脚本(clean-redcap.ps1) + +```powershell +#!/usr/bin/env pwsh +# clean-redcap.ps1 - 清理REDCap环境(危险操作!) + +Write-Host "🗑️ REDCap Environment Cleanup" -ForegroundColor Red +Write-Host "" +Write-Host "⚠️ WARNING: This will DELETE ALL DATA!" -ForegroundColor Red +Write-Host "" + +$confirm = Read-Host "Type 'YES' to confirm deletion" + +if ($confirm -ne "YES") { + Write-Host "❌ Cleanup cancelled." -ForegroundColor Yellow + exit 0 +} + +Write-Host "" +Write-Host "🗑️ Removing containers..." -ForegroundColor Yellow +docker-compose down + +Write-Host "🗑️ Removing volumes (DATA LOSS!)..." -ForegroundColor Red +docker-compose down --volumes + +Write-Host "🗑️ Removing images..." -ForegroundColor Yellow +docker rmi redcap-docker-dev_redcap-web + +Write-Host "" +Write-Host "✅ Cleanup Complete!" -ForegroundColor Green +Write-Host " Run 'setup-redcap.ps1' to redeploy." -ForegroundColor Cyan +``` + +--- + +## 🎯 九、决策清单 + +在实施部署前,请确认以下决策: + +### 9.1 必需决策 + +| 决策项 | 选项 | 推荐 | 您的选择 | +|--------|------|------|---------| +| **部署位置** | `redcap-docker-dev/` | ✅ 推荐 | [ ] | +| **REDCap端口** | 8080 / 其他 | 8080 | [ ] | +| **MySQL端口** | 3306 / 其他 | 3306 | [ ] | +| **phpMyAdmin** | 需要 / 不需要 | 需要 | [ ] | +| **SMTP配置** | 跳过 / 配置 | 跳过 | [ ] | +| **数据持久化** | 命名卷 / 绑定挂载 | 命名卷 | [ ] | + +### 9.2 环境变量 + +```bash +# 确认以下密码(开发环境) +MYSQL_ROOT_PASSWORD=redcap_root_123 # 同意 [ ] +MYSQL_DATABASE=redcap # 同意 [ ] +MYSQL_USER=redcap_user # 同意 [ ] +MYSQL_PASSWORD=redcap_pass_456 # 同意 [ ] + +# Salt值(重要!一旦设置不可更改) +REDCAP_SALT=iit_dev_salt_2026_redcap_v15 # 同意 [ ] +``` + +### 9.3 端口冲突检查 + +```powershell +# 请先运行以下命令检查端口 +netstat -ano | findstr :8080 # REDCap +netstat -ano | findstr :3306 # MySQL +netstat -ano | findstr :8081 # phpMyAdmin + +# 如果有冲突,记录需要修改的端口: +# REDCap端口改为:_______ +# MySQL端口改为:_______ +# phpMyAdmin端口改为:_______ +``` + +--- + +## 📝 十、后续步骤 + +### 10.1 Day 2开发准备 + +部署完成后,立即可以开始: + +``` +✅ REDCap API Adapter开发 + - exportRecords() 实现 + - importRecords() 实现 + - exportMetadata() 实现 + +✅ 真实API测试 + - 使用实际API Token + - 验证JSON响应格式 + - 测试错误处理 + +✅ SyncManager开发 + - 混合同步模式(Webhook + Polling) + - 数据增量拉取 + - pg-boss任务调度 +``` + +### 10.2 External Module开发(Day 8) + +``` +当需要开发External Module时: +1. 在 redcap15.8.0/redcap/modules/ 创建模块目录 +2. 编写 config.json 和 Module.php +3. 容器会自动挂载(因为使用卷映射) +4. REDCap控制中心启用模块 +``` + +### 10.3 迁移到生产环境(未来) + +``` +本地开发验证通过后: +1. 在阿里云ECS标准安装REDCap(LAMP) +2. 配置RDS MySQL(高可用) +3. 配置OSS存储(edocs目录) +4. 配置SSL证书(Let's Encrypt) +5. 配置SMTP(阿里云DirectMail) +6. 复制External Module到生产环境 +7. 导入测试项目(或从头创建) +``` + +--- + +## 🔗 十一、相关文档 + +### 11.1 项目文档 + +- [REDCap二次开发深度指南](./REDCap%20二次开发深度指南.md) - REDCap架构和EM开发 +- [REDCap部署指南与环境要求](./02-REDCap部署指南与环境要求.md) - 生产环境部署 +- [IIT Manager Agent技术方案 V1.1](../IIT%20Manager%20Agent/02-技术设计/IIT%20Manager%20Agent%20完整技术开发方案%20(V1.1).md) - REDCap集成方案 +- [MVP开发任务清单](../IIT%20Manager%20Agent/04-开发计划/MVP开发任务清单.md) - Day 2任务 + +### 11.2 官方文档 + +- REDCap官网:https://projectredcap.org/ +- REDCap API文档:https://redcap.vanderbilt.edu/api/help/ +- External Module文档:https://github.com/vanderbilt-redcap/external-module-framework-docs + +### 11.3 Docker文档 + +- Docker Compose:https://docs.docker.com/compose/ +- Docker PHP镜像:https://hub.docker.com/_/php +- Docker MySQL镜像:https://hub.docker.com/_/mysql + +--- + +## 📞 十二、故障排查 + +### 12.1 容器无法启动 + +```powershell +# 检查Docker状态 +docker info + +# 查看容器日志 +docker-compose logs + +# 检查端口占用 +netstat -ano | findstr :8080 +netstat -ano | findstr :3306 + +# 重建容器 +docker-compose down +docker-compose up -d --force-recreate +``` + +### 12.2 无法访问REDCap + +```powershell +# 检查容器运行状态 +docker-compose ps + +# 检查Apache日志 +docker-compose logs redcap-web + +# 进入容器诊断 +docker exec -it redcap-web bash +curl localhost +``` + +### 12.3 数据库连接失败 + +```powershell +# 检查MySQL日志 +docker-compose logs redcap-db + +# 测试MySQL连接 +docker exec -it redcap-mysql mysql -uredcap_user -predcap_pass_456 -e "SHOW DATABASES;" + +# 检查database.php配置 +docker exec -it redcap-web cat /var/www/html/redcap/database.php +``` + +### 12.4 API调用失败 + +```powershell +# 验证API Token +# REDCap → Applications → API → 查看Token + +# 测试API连接 +curl -X POST http://localhost:8080/api/ ` + -d "token=YOUR_TOKEN" ` + -d "content=version" + +# 应该返回REDCap版本号 +``` + +--- + +## ✅ 十三、部署成功标志 + +当您看到以下所有指标时,表示部署成功: + +``` +✅ 核心容器状态(必需) + - redcap-mysql: Up + - redcap-web: Up + +⭐ 辅助容器状态(可选,仅开发环境) + - redcap-phpmyadmin: Up(可选,生产环境禁用) + +✅ 服务可访问 + - http://localhost:8080 → REDCap登录页(核心) + - http://localhost:8081 → phpMyAdmin界面(可选,调试用) + +✅ 功能验证 + - 管理员登录成功 + - 测试项目已创建 + - API Token已生成 + - API调用返回数据 + +✅ 后端集成 + - .env配置完成 + - API测试脚本通过 + - Node.js可访问REDCap + +说明: +- phpMyAdmin是可选的开发调试工具 +- 生产环境出于安全考虑应禁用 +- 不影响REDCap核心功能 +``` + +--- + +## 🏗️ 十四、生产环境部署指南 + +### 14.1 本地开发 → 生产环境迁移路径 + +```yaml +阶段1: 本地开发环境(当前) +├─ 目的:API开发、EM调试 +├─ 环境:Windows/Mac + Docker Desktop +├─ 数据库:Docker MySQL容器 +├─ 辅助工具:phpMyAdmin(调试) +└─ 成本:$0 + +阶段2: 阿里云测试环境 +├─ 目的:集成测试、性能测试 +├─ 服务器:阿里云ECS(2核4GB) +├─ 数据库:阿里云RDS MySQL基础版 +├─ 存储:云盘(40GB ESSD) +├─ 域名:test-redcap.yourdomain.com +└─ 成本:¥500-700/月 + +阶段3: 阿里云生产环境 +├─ 目的:正式生产运行 +├─ 服务器:阿里云ECS(4核8GB) +├─ 数据库:阿里云RDS MySQL高可用版 +├─ 存储:云盘(100GB ESSD) + OSS备份 +├─ 负载均衡:阿里云SLB + SSL证书 +├─ 监控:CloudMonitor + 日志服务 +├─ 域名:redcap.yourdomain.com +└─ 成本:¥1500-2000/月 + +阶段4: 医院私有化部署 +├─ 目的:医院内网运行 +├─ 服务器:医院提供服务器 +├─ 数据库:Docker MySQL 或 医院MySQL服务器 +├─ 部署方式:Docker离线镜像包 +├─ 交付物:一键部署脚本 + 培训手册 +└─ 成本:一次性部署费用 +``` + +### 14.2 生产环境Docker配置调整 + +#### 调整1:移除phpMyAdmin + +```yaml +# docker-compose.yml 生产环境版本 + +services: + redcap-db: + # ... MySQL配置保持不变 + + redcap-web: + # ... REDCap配置保持不变 + + # ❌ 移除phpMyAdmin(安全考虑) + # phpmyadmin: + # ... + +# 生产环境数据库管理方式: +# 1. 使用阿里云RDS控制台 +# 2. SSH连接ECS后使用mysql命令行 +# 3. 受限的DMS数据管理服务 +``` + +#### 调整2:使用RDS MySQL + +```yaml +# docker-compose.yml 生产环境版本 + +services: + # ❌ 移除redcap-db容器(使用RDS) + # redcap-db: + # ... + + redcap-web: + image: redcap-web:v1.0 + environment: + # 连接阿里云RDS + REDCAP_DB_HOST: rm-xxxxxx.mysql.rds.aliyuncs.com + REDCAP_DB_PORT: 3306 + REDCAP_DB_NAME: redcap_prod + REDCAP_DB_USER: redcap_user + REDCAP_DB_PASS: ${MYSQL_PASSWORD} # 从环境变量读取 + # ... 其他配置 +``` + +#### 调整3:配置SSL证书 + +```yaml +# docker-compose.yml 生产环境版本 + +services: + redcap-web: + volumes: + # 挂载SSL证书 + - ./ssl/cert.pem:/etc/ssl/certs/redcap.crt:ro + - ./ssl/key.pem:/etc/ssl/private/redcap.key:ro + ports: + - "80:80" + - "443:443" # HTTPS端口 +``` + +#### 调整4:资源限制 + +```yaml +# docker-compose.yml 生产环境版本 + +services: + redcap-web: + deploy: + resources: + limits: + cpus: '2' + memory: 4G + reservations: + cpus: '1' + memory: 2G + restart: always # 自动重启 +``` + +#### 调整5:日志管理 + +```yaml +# docker-compose.yml 生产环境版本 + +services: + redcap-web: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +### 14.3 生产环境安全加固 + +```yaml +必做项: +├─ 修改所有默认密码(MySQL、REDCap admin) +├─ 启用HTTPS(强制) +├─ 配置防火墙规则(仅开放80/443端口) +├─ 禁用phpMyAdmin(移除容器) +├─ 配置定期自动备份(数据库 + 文件) +├─ 配置监控告警(CPU、内存、磁盘、服务状态) +├─ 限制SSH访问(密钥认证 + IP白名单) +└─ 定期更新安全补丁 + +推荐项: +├─ 使用阿里云SLB做负载均衡和SSL卸载 +├─ 配置WAF(Web应用防火墙) +├─ 启用RDS自动备份(每日备份,保留7天) +├─ 配置OSS存储备份(异地容灾) +└─ 使用CloudMonitor实时监控 +``` + +### 14.4 生产环境成本估算 + +```yaml +阿里云生产环境配置: + +计算资源: +├─ ECS 4核8GB:¥400/月 +├─ 云盘 100GB ESSD:¥50/月 +└─ 小计:¥450/月 + +数据库: +├─ RDS MySQL高可用版 2核4GB:¥600/月 +├─ 存储 100GB:包含 +└─ 小计:¥600/月 + +网络与安全: +├─ SLB负载均衡:¥60/月 +├─ SSL证书:¥100/年(Let's Encrypt免费) +├─ 公网流量:¥0.8/GB(估算¥50/月) +└─ 小计:¥110/月 + +存储与备份: +├─ OSS存储 100GB:¥10/月 +├─ OSS流量:¥10/月 +└─ 小计:¥20/月 + +监控与日志: +├─ CloudMonitor:免费 +├─ 日志服务 10GB:¥5/月 +└─ 小计:¥5/月 + +总计:¥1185/月(约¥14,220/年) + +优化方案(包年): +├─ ECS 4核8GB(3年):¥3600/年(¥300/月) +├─ RDS MySQL高可用版:¥600/月 +├─ 其他:¥135/月 +└─ 总计:¥1035/月(约¥12,420/年) +``` + +### 14.5 医院私有化部署交付清单 + +```yaml +交付物清单: + +1. Docker镜像包: + ├─ redcap-web:v1.0.tar(导出的镜像文件) + ├─ mysql:8.0.tar(如医院无数据库) + └─ docker-compose.yml(配置文件) + +2. 部署脚本: + ├─ install-docker.sh(Docker安装脚本) + ├─ setup-redcap.sh(一键部署脚本) + ├─ start-redcap.sh(启动脚本) + ├─ stop-redcap.sh(停止脚本) + └─ backup-redcap.sh(备份脚本) + +3. 文档: + ├─ 部署指南.pdf(医院IT版) + ├─ 运维手册.pdf(日常操作) + ├─ 故障排查手册.pdf(问题诊断) + └─ 安全加固指南.pdf(合规要求) + +4. 配置模板: + ├─ database.php.template(数据库配置) + ├─ php.ini.template(PHP配置) + ├─ apache.conf.template(Apache配置) + └─ .env.template(环境变量) + +5. 培训材料: + ├─ 系统架构说明.pptx + ├─ 日常运维培训.pptx + └─ 操作演示视频.mp4 + +部署流程: +Step 1: 医院IT安装Docker(30分钟) +Step 2: 导入Docker镜像(10分钟) +Step 3: 配置环境变量(10分钟) +Step 4: 启动容器(5分钟) +Step 5: 初始化REDCap(30分钟) +Step 6: 验证功能(30分钟) +总计:约2小时 +``` + +### 14.6 生产环境监控方案 + +```yaml +监控指标: + +系统层: +├─ CPU使用率(告警阈值:>80% 持续5分钟) +├─ 内存使用率(告警阈值:>85%) +├─ 磁盘使用率(告警阈值:>80%) +└─ 网络流量(异常流量告警) + +应用层: +├─ REDCap可用性(HTTP健康检查,5分钟间隔) +├─ 响应时间(告警阈值:>3秒) +├─ 错误率(告警阈值:>1%) +└─ 并发用户数 + +数据库层: +├─ RDS连接数(告警阈值:>80%) +├─ 慢查询数(>1秒的查询) +├─ 磁盘IOPS使用率 +└─ CPU使用率 + +容器层: +├─ 容器运行状态(自动重启监控) +├─ 容器资源使用(内存泄漏检测) +└─ 容器日志错误率 + +告警方式: +├─ 短信(紧急告警) +├─ 邮件(一般告警) +├─ 钉钉/企业微信(团队通知) +└─ CloudMonitor控制台 +``` + +--- + +## 🎉 结语 + +### 本地开发环境部署完成 ✅ + +**恭喜!您已掌握REDCap Docker部署方案。** + +这套Docker配置具有以下特点: +- ✅ **开发/生产架构一致**:消除环境漂移 +- ✅ **可直接用于生产**:经过少量调整即可 +- ✅ **支持离线交付**:医院私有化部署 +- ✅ **2人团队可维护**:简单、透明、可控 + +### 下一步行动 + +**立即开始**: +- Day 2:开始REDCap API Adapter开发 +- 参考:[MVP开发任务清单](../IIT%20Manager%20Agent/04-开发计划/MVP开发任务清单.md) + +**未来规划**: +- Week 2-3:阿里云ECS测试环境部署 +- Month 1-2:医院试点部署 +- Month 3+:标准化交付流程 + +### 需要帮助? + +- 查看本文档的"故障排查"章节 +- 查看Docker容器日志:`docker-compose logs` +- 参考REDCap官方文档:https://projectredcap.org/ +- 参考ECS决议报告:[REDCap生产环境部署:ECS vs SAE深度决议报告](./REDCap%20生产环境部署:ECS%20vs%20SAE%20深度决议报告.md) + +--- + +> **文档维护**:本文档随IIT Manager Agent项目持续更新 +> **版本历史**: +> - v1.0 (2026-01-01): 初始版本 +> - v2.0 (2026-01-01): 根据ECS决议报告修订,强调开发/生产一致性 +> **最后更新**:2026-01-01 +> **下次审查**:生产环境首次部署后 + diff --git a/docs/03-业务模块/Redcap/REDCap 生产环境部署:ECS vs SAE 深度决议报告.md b/docs/03-业务模块/Redcap/REDCap 生产环境部署:ECS vs SAE 深度决议报告.md new file mode 100644 index 00000000..ad853b7f --- /dev/null +++ b/docs/03-业务模块/Redcap/REDCap 生产环境部署:ECS vs SAE 深度决议报告.md @@ -0,0 +1,53 @@ +# **REDCap 生产环境部署:ECS vs SAE 深度决议报告** + +## **1\. 核心结论:认可 ECS 优先策略** + +针对 IIT Manager Agent 项目,我们决定将 REDCap 生产环境部署在 **ECS (Docker 模式)** 运行,而不是 SAE。 + +### **为什么我们“认错”并转向 ECS?** + +在讨论 AI 后端时,SAE 的免运维特性很吸引人,但 REDCap 的三个“致命特性”决定了它在 SAE 上会极其痛苦: + +1. **Cron 依赖(心跳丢失)**:REDCap 每分钟都需要运行一次 cron.php。在 SAE 中,你得额外买 SchedulerX 服务;在 ECS,只需一行 crontab 就能搞定且 100% 可靠。 +2. **Session 粘滞(掉线噩梦)**:REDCap 默认将会话存本地。SAE 是多实例的,如果没做 Redis 共享,用户登录后会反复掉线,2 人团队去修这个 Bug 会耗费大量时间。 +3. **文件系统 POSIX 依赖**:REDCap 像 10 年前的软件一样极其依赖本地文件夹读写。SAE 必须挂载 NAS,网络延迟会拖慢整个系统的响应。 + +## **2\. 深度对比:务实派的决策依据** + +| 维度 | ECS \+ Docker (我们的选择) | SAE (Serverless) | 结论 | +| :---- | :---- | :---- | :---- | +| **部署成本** | **低**。入门级 ECS (2核4G) 约 1500元/年。 | **高**。SAE \+ NAS \+ 闲置费用可能更贵。 | **ECS 胜** | +| **配置复杂度** | **极简**。只需运行 docker-compose.yml。 | **复杂**。需解决共享存储、Session同步、定时任务。 | **ECS 胜** | +| **系统透明度** | **透明**。直接 docker logs 查看 PHP 日志。 | **黑盒**。云原生链路长,报错时排查难度大。 | **ECS 胜** | +| **可移植性** | **最强**。这份 Docker 配置可以原封不动挪到医院内网。 | **差**。医院内网通常没有 SAE 这种环境。 | **ECS 胜** | + +## **3\. 2 人团队的“生存之道”** + +作为一个只有 2 人的团队,我们的时间应该花在 **Agent 的 Prompt 调优** 和 **业务逻辑** 上,而不是花在“调试云产品之间的连接”上。 + +* **ECS 方案**:你就像拥有了一台真正的电脑。文件在哪、日志在哪、数据库连没连上,你一眼就能看清。 +* **SAE 方案**:你会陷入“为什么挂载了 NAS 还是没写权限?”、“为什么 Cron 没触发?”这种与业务无关的琐事中。 + +## **4\. 最终定稿:混合架构蓝图** + +我们将采取\*\*“混合云”\*\*的思路,发挥各自的长处: + +### **4.1 数据平面 (Data Layer) \-\> 部署在 ECS** + +* **组件**:REDCap (Apache \+ PHP 8.1)。 +* **方式**:使用 Docker-Compose 运行。 +* **存储**:附件存储在 ECS 挂载的云盘;数据库连接 **RDS MySQL**。 +* **优势**:保证了 EDC 系统的绝对稳定和传统运维的简便。 + +### **4.2 控制平面 (AI Agent Layer) \-\> 部署在 SAE** + +* **组件**:Node.js 后端、Python 算法、AI 前端。 +* **方式**:Serverless 部署。 +* **优势**:利用 SAE 处理 AI 这种流量波动大、需要弹性伸缩的模块。 + +## **5\. 对后续开发的意义** + +1. **本地环境即生产环境**:由于 ECS 跑的是 Docker,你在本地 03-REDCap本地部署方案.md 里写的代码,直接就能上线,没有任何“环境漂移”。 +2. **离线交付预演**:如果未来医院要求内网部署,我们已经有了一套完整的、基于 ECS/Docker 的交付包,这比 SAE 方案更容易被医院 IT 接受。 + +**当前状态**:Deployment Strategy Locked | **建议**:立即执行基于 ECS 的生产环境搭建。 \ No newline at end of file diff --git a/redcap-docker-dev/.gitattributes b/redcap-docker-dev/.gitattributes new file mode 100644 index 00000000..b8f0ccb6 --- /dev/null +++ b/redcap-docker-dev/.gitattributes @@ -0,0 +1,34 @@ +# Git attributes for REDCap Docker deployment +# 确保跨平台一致性,防止CRLF/LF问题 + +# PHP文件统一使用LF换行符(Linux标准) +*.php text eol=lf +*.inc text eol=lf + +# Shell脚本统一使用LF +*.sh text eol=lf + +# PowerShell脚本保持CRLF(Windows标准) +*.ps1 text eol=crlf + +# 配置文件统一使用LF +*.conf text eol=lf +*.ini text eol=lf +*.yml text eol=lf +*.yaml text eol=lf + +# Markdown和文档 +*.md text eol=lf +*.txt text eol=lf + +# 二进制文件不做转换 +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.pdf binary +*.zip binary +*.tar binary +*.gz binary + diff --git a/redcap-docker-dev/.gitignore b/redcap-docker-dev/.gitignore new file mode 100644 index 00000000..ef4987f4 --- /dev/null +++ b/redcap-docker-dev/.gitignore @@ -0,0 +1,65 @@ +# REDCap Docker环境 - Git忽略文件 +# 版本:v1.0 +# 日期:2026-01-01 + +# ========== 环境变量文件(包含敏感信息) ========== +.env +.env.local +.env.*.local + +# ========== Docker数据卷挂载点(如使用本地挂载) ========== +data/ +mysql-data/ +edocs/ +temp/ +modules/ + +# ========== SSL证书(敏感) ========== +ssl/ +*.crt +*.key +*.pem + +# ========== 日志文件 ========== +logs/ +*.log + +# ========== 备份文件 ========== +backups/ +*.sql +*.tar +*.tar.gz +*.zip + +# ========== 临时文件 ========== +tmp/ +temp/ +*.tmp +*.swp +*~ + +# ========== IDE配置 ========== +.vscode/ +.idea/ +*.code-workspace + +# ========== 操作系统文件 ========== +# Windows +Thumbs.db +Desktop.ini + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# ========== 其他 ========== +# 不要忽略README.md +!README.md + +# 不要忽略配置模板 +!env.template +!*.example +!*.template + + diff --git a/redcap-docker-dev/Dockerfile.redcap b/redcap-docker-dev/Dockerfile.redcap new file mode 100644 index 00000000..b2cbcd37 --- /dev/null +++ b/redcap-docker-dev/Dockerfile.redcap @@ -0,0 +1,94 @@ +# REDCap Docker镜像定义 +# 基于:PHP 8.1 Apache官方镜像 +# 版本:v1.0 +# 日期:2026-01-01 +# 适用:开发/测试/生产环境 + +FROM php:8.1-apache + +LABEL maintainer="IIT Manager Team" +LABEL description="REDCap 15.8.0 Docker Image for IIT Manager Agent" +LABEL version="1.0" + +# ========== 设置时区 ========== +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# ========== 配置APT使用阿里云镜像源(加速国内构建) ========== +RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources || \ + sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list + +# ========== 安装系统依赖 ========== +RUN apt-get update && apt-get install -y \ + # 图片处理库(GD扩展需要) + libpng-dev \ + libjpeg-dev \ + libfreetype6-dev \ + # ZIP扩展 + libzip-dev \ + # LDAP扩展(可选,企业认证用) + libldap2-dev \ + # SOAP扩展(可选,Web Service用) + libxml2-dev \ + # Cron定时任务 + cron \ + # 常用工具 + curl \ + vim \ + unzip \ + # 清理APT缓存 + && rm -rf /var/lib/apt/lists/* + +# ========== 安装PHP扩展 ========== +# GD扩展(图片处理) +RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \ + docker-php-ext-install -j$(nproc) gd + +# 数据库扩展 +RUN docker-php-ext-install -j$(nproc) \ + mysqli \ + pdo_mysql + +# 其他必需扩展 +RUN docker-php-ext-install -j$(nproc) \ + zip \ + soap \ + calendar \ + bcmath + +# LDAP扩展(可选) +RUN docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \ + docker-php-ext-install ldap + +# ========== 启用Apache模块 ========== +RUN a2enmod rewrite ssl headers + +# ========== 创建必需目录 ========== +RUN mkdir -p /var/www/html/redcap/edocs && \ + mkdir -p /var/www/html/redcap/temp && \ + mkdir -p /var/www/html/redcap/modules && \ + chown -R www-data:www-data /var/www/html + +# ========== 配置Cron定时任务 ========== +# REDCap需要定期运行cron.php +RUN echo "* * * * * www-data /usr/local/bin/php /var/www/html/redcap/cron.php > /proc/1/fd/1 2>&1" >> /etc/crontab && \ + echo "" >> /etc/crontab + +# ========== 复制启动脚本 ========== +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +# ========== 暴露端口 ========== +EXPOSE 80 443 + +# ========== 健康检查 ========== +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD curl -f http://localhost/ || exit 1 + +# ========== 工作目录 ========== +WORKDIR /var/www/html + +# ========== 启动命令 ========== +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +CMD ["apache2-foreground"] + diff --git a/redcap-docker-dev/README.md b/redcap-docker-dev/README.md new file mode 100644 index 00000000..5daa36d0 --- /dev/null +++ b/redcap-docker-dev/README.md @@ -0,0 +1,366 @@ +# REDCap Docker部署环境 + +> **IIT Manager Agent项目 - REDCap开发/生产一致性环境** +> 版本:v1.0 | 日期:2026-01-01 + +--- + +## 📋 目录 + +1. [快速开始](#快速开始) +2. [项目结构](#项目结构) +3. [环境要求](#环境要求) +4. [详细部署步骤](#详细部署步骤) +5. [常用命令](#常用命令) +6. [故障排查](#故障排查) +7. [生产环境部署](#生产环境部署) + +--- + +## 🚀 快速开始 + +### 一键部署(推荐) + +```powershell +# 进入项目目录 +cd redcap-docker-dev + +# 运行一键部署脚本 +.\scripts\setup-redcap.ps1 + +# 访问REDCap +# http://localhost:8080/install.php +``` + +### 手动部署 + +```powershell +# 1. 复制环境变量模板 +copy env.template .env + +# 2. 构建并启动容器 +docker-compose up -d + +# 3. 查看容器状态 +docker-compose ps +``` + +--- + +## 📁 项目结构 + +``` +redcap-docker-dev/ +├── docker-compose.yml # Docker编排(开发环境) +├── docker-compose.prod.yml # Docker编排(生产环境) +├── Dockerfile.redcap # REDCap镜像定义 +├── docker-entrypoint.sh # 容器启动脚本 +├── env.template # 环境变量模板 +├── .gitignore # Git忽略规则 +│ +├── config/ # 配置文件目录 +│ ├── apache/ +│ │ └── redcap.conf # Apache虚拟主机配置 +│ ├── php/ +│ │ └── php.ini # PHP配置 +│ └── database.php # REDCap数据库配置 +│ +├── scripts/ # 运维脚本 +│ ├── setup-redcap.ps1 # 一键部署 +│ ├── start-redcap.ps1 # 启动服务 +│ ├── stop-redcap.ps1 # 停止服务 +│ ├── logs-redcap.ps1 # 查看日志 +│ └── clean-redcap.ps1 # 清理环境 +│ +└── README.md # 本文档 +``` + +--- + +## 💻 环境要求 + +### 软件要求 + +- **Docker Desktop**:20.10+ (Windows/Mac) +- **PowerShell**:5.1+ 或 PowerShell Core 7+ +- **内存**:至少4GB可用 +- **磁盘**:至少10GB可用空间 + +### REDCap源码 + +确保REDCap源码位于正确位置: +``` +AIclinicalresearch/ +├── redcap15.8.0/ +│ └── redcap/ +└── redcap-docker-dev/ # 当前目录 +``` + +--- + +## 📖 详细部署步骤 + +### 步骤1:准备环境变量 + +```powershell +# 复制模板 +copy env.template .env + +# (可选)编辑.env修改密码 +notepad .env +``` + +**默认配置(开发环境)**: +- MySQL Root密码:`redcap_root_dev_2026` +- MySQL数据库:`redcap` +- MySQL用户:`redcap_user` +- MySQL密码:`redcap_pass_dev_456` + +⚠️ **生产环境必须修改所有密码!** + +### 步骤2:构建Docker镜像 + +```powershell +docker-compose build +``` + +**预计时间**:5-10分钟(首次) + +### 步骤3:启动容器 + +```powershell +docker-compose up -d +``` + +**启动的服务**: +- `redcap-mysql`:MySQL 8.0数据库 +- `redcap-apache`:REDCap Web服务 +- `redcap-phpmyadmin`:数据库管理工具(可选) + +### 步骤4:等待服务就绪 + +```powershell +# 等待30秒让MySQL完全启动 +# 然后访问:http://localhost:8080/install.php +``` + +### 步骤5:安装REDCap + +访问:http://localhost:8080/install.php + +**数据库配置**: +- Hostname:`redcap-db` +- Database:`redcap` +- Username:`redcap_user` +- Password:`redcap_pass_dev_456` +- Salt:`iit_dev_salt_2026_redcap_v15_do_not_change` + +**管理员账户(示例)**: +- Username:`admin` +- Password:`Admin@123456`(开发环境) +- Email:`dev@example.com` + +**SMTP配置**: +- 选择"Skip SMTP Configuration"(开发环境不需要邮件) + +--- + +## 🔧 常用命令 + +### 启动/停止 + +```powershell +# 启动服务 +.\scripts\start-redcap.ps1 + +# 停止服务(保留数据) +.\scripts\stop-redcap.ps1 + +# 重启服务 +.\scripts\stop-redcap.ps1 +.\scripts\start-redcap.ps1 +``` + +### 查看日志 + +```powershell +# 查看所有服务日志 +.\scripts\logs-redcap.ps1 + +# 查看特定服务 +.\scripts\logs-redcap.ps1 -Service redcap-web + +# 实时跟踪日志 +.\scripts\logs-redcap.ps1 -Follow + +# 显示更多行 +.\scripts\logs-redcap.ps1 -Tail 100 +``` + +### 容器管理 + +```powershell +# 查看容器状态 +docker-compose ps + +# 进入容器 +docker exec -it redcap-apache bash + +# 重启特定容器 +docker-compose restart redcap-web + +# 查看资源使用 +docker stats +``` + +### 数据库管理 + +```powershell +# 通过phpMyAdmin +# 访问:http://localhost:8081 +# 用户:root +# 密码:redcap_root_dev_2026 + +# 或通过命令行 +docker exec -it redcap-mysql mysql -uroot -predcap_root_dev_2026 redcap +``` + +### 清理环境 + +```powershell +# 完全清理(删除所有数据) +.\scripts\clean-redcap.ps1 +``` + +⚠️ **警告**:此命令会删除所有数据,无法恢复! + +--- + +## 🔍 故障排查 + +### 问题1:容器无法启动 + +```powershell +# 检查Docker状态 +docker info + +# 查看容器日志 +docker-compose logs + +# 检查端口占用 +netstat -ano | findstr :8080 +``` + +### 问题2:无法访问REDCap + +```powershell +# 检查容器运行状态 +docker-compose ps + +# 检查Apache日志 +docker-compose logs redcap-web + +# 进入容器诊断 +docker exec -it redcap-apache bash +curl localhost +``` + +### 问题3:数据库连接失败 + +```powershell +# 检查MySQL日志 +docker-compose logs redcap-db + +# 等待MySQL完全启动(30秒) +Start-Sleep -Seconds 30 + +# 测试连接 +docker exec -it redcap-mysql mysql -uredcap_user -predcap_pass_dev_456 -e "SHOW DATABASES;" +``` + +### 问题4:端口冲突 + +```powershell +# 修改docker-compose.yml中的端口映射 +# 例如将8080改为8888: +ports: + - "8888:80" # 主机端口:容器端口 +``` + +--- + +## 🏗️ 生产环境部署 + +### 使用生产配置 + +```powershell +# 使用生产环境配置文件 +docker-compose -f docker-compose.prod.yml up -d +``` + +### 关键差异 + +| 配置项 | 开发环境 | 生产环境 | +|--------|---------|---------| +| **phpMyAdmin** | ✅ 启用 | ❌ 禁用(安全) | +| **MySQL** | Docker容器 | 阿里云RDS(推荐) | +| **密码** | 简单密码 | 强密码(32+字符) | +| **SSL** | 不需要 | 必需(HTTPS) | +| **日志** | 详细 | 精简 | +| **资源限制** | 无 | 配置限制 | + +### 生产环境检查清单 + +- [ ] 修改所有默认密码 +- [ ] 配置RDS MySQL连接 +- [ ] 移除phpMyAdmin容器 +- [ ] 启用HTTPS(SSL证书) +- [ ] 配置防火墙规则 +- [ ] 配置自动备份 +- [ ] 配置监控告警 +- [ ] 限制SSH访问 + +### 详细生产部署文档 + +参考:`docs/03-业务模块/Redcap/03-REDCap本地Docker开发环境部署方案.md` + +--- + +## 📚 相关文档 + +- [REDCap本地Docker开发环境部署方案](../../docs/03-业务模块/Redcap/03-REDCap本地Docker开发环境部署方案.md) +- [REDCap生产环境部署:ECS vs SAE深度决议报告](../../docs/03-业务模块/Redcap/REDCap%20生产环境部署:ECS%20vs%20SAE%20深度决议报告.md) +- [REDCap二次开发深度指南](../../docs/03-业务模块/Redcap/REDCap%20二次开发深度指南.md) +- [IIT Manager Agent MVP开发任务清单](../../docs/03-业务模块/IIT%20Manager%20Agent/04-开发计划/MVP开发任务清单.md) + +--- + +## 📞 技术支持 + +**需要帮助?** + +1. 查看详细文档(上方链接) +2. 查看容器日志:`.\scripts\logs-redcap.ps1` +3. 参考REDCap官方文档:https://projectredcap.org/ +4. 联系IIT Manager开发团队 + +--- + +## 🎯 下一步 + +**部署成功后**: + +1. ✅ **完成REDCap安装**(install.php) +2. ✅ **创建测试项目**(IIT试验项目) +3. ✅ **生成API Token** +4. ✅ **开始Day 2开发**(REDCap API Adapter) + +参考:[MVP开发任务清单](../../docs/03-业务模块/IIT%20Manager%20Agent/04-开发计划/MVP开发任务清单.md) + +--- + +> **文档维护**:IIT Manager开发团队 +> **最后更新**:2026-01-01 +> **版本**:v1.0 + + diff --git a/redcap-docker-dev/config/apache/redcap.conf b/redcap-docker-dev/config/apache/redcap.conf new file mode 100644 index 00000000..4df5e161 --- /dev/null +++ b/redcap-docker-dev/config/apache/redcap.conf @@ -0,0 +1,126 @@ +# REDCap Apache虚拟主机配置 +# 版本:v1.0 +# 日期:2026-01-01 +# 适用:开发/测试/生产环境 + + + ServerName localhost + ServerAdmin admin@localhost + DocumentRoot /var/www/html/redcap + + # ========== 目录配置 ========== + + # 禁止目录浏览(安全) + Options -Indexes +FollowSymLinks + + # 允许.htaccess覆盖 + AllowOverride All + + # 访问权限 + Require all granted + + # 默认首页 + DirectoryIndex index.php index.html + + + # ========== 限制特定目录访问(安全) ========== + # 禁止直接访问temp目录 + + Require all denied + + + # 禁止直接访问modules源码(仅允许通过REDCap访问) + + Require all denied + + + # ========== 日志配置 ========== + ErrorLog ${APACHE_LOG_DIR}/redcap-error.log + CustomLog ${APACHE_LOG_DIR}/redcap-access.log combined + + # 日志级别(开发环境:info,生产环境:warn) + LogLevel warn + + # ========== 安全头(推荐) ========== + # 防止点击劫持 + Header always set X-Frame-Options "SAMEORIGIN" + + # 防止MIME类型嗅探 + Header always set X-Content-Type-Options "nosniff" + + # XSS保护 + Header always set X-XSS-Protection "1; mode=block" + + # Referrer策略 + Header always set Referrer-Policy "strict-origin-when-cross-origin" + + # ========== PHP配置覆盖 ========== + # 文件上传限制 + php_value upload_max_filesize 32M + php_value post_max_size 32M + + # 执行时间限制(数据导出需要) + php_value max_execution_time 300 + php_value max_input_time 300 + + # 内存限制 + php_value memory_limit 256M + + # ========== 性能优化 ========== + # 启用gzip压缩(暂时禁用,解决浏览器解码问题) + # + # AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json + # + + # 浏览器缓存(静态资源) + + ExpiresActive On + ExpiresByType image/jpg "access plus 1 month" + ExpiresByType image/jpeg "access plus 1 month" + ExpiresByType image/png "access plus 1 month" + ExpiresByType image/gif "access plus 1 month" + ExpiresByType text/css "access plus 1 week" + ExpiresByType application/javascript "access plus 1 week" + + + +# ========== HTTPS配置(生产环境) ========== +# 生产环境应启用HTTPS,取消下方注释并配置SSL证书: + +# +# ServerName redcap.yourdomain.com +# ServerAdmin admin@yourdomain.com +# DocumentRoot /var/www/html/redcap +# +# # SSL证书配置 +# SSLEngine on +# SSLCertificateFile /etc/ssl/certs/redcap.crt +# SSLCertificateKeyFile /etc/ssl/private/redcap.key +# # 如有中间证书: +# # SSLCertificateChainFile /etc/ssl/certs/intermediate.crt +# +# # SSL安全配置 +# SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +# SSLCipherSuite HIGH:!aNULL:!MD5:!3DES +# SSLHonorCipherOrder on +# +# # HSTS(强制HTTPS) +# Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" +# +# # 其他配置同上(Directory、Log等) +# +# Options -Indexes +FollowSymLinks +# AllowOverride All +# Require all granted +# +# +# ErrorLog ${APACHE_LOG_DIR}/redcap-ssl-error.log +# CustomLog ${APACHE_LOG_DIR}/redcap-ssl-access.log combined +# + +# ========== HTTP强制跳转HTTPS(生产环境启用) ========== +# +# ServerName redcap.yourdomain.com +# Redirect permanent / https://redcap.yourdomain.com/ +# + diff --git a/redcap-docker-dev/config/database.php b/redcap-docker-dev/config/database.php new file mode 100644 index 00000000..722f99fd --- /dev/null +++ b/redcap-docker-dev/config/database.php @@ -0,0 +1,137 @@ +/dev/null || echo "deflate module not enabled" +echo "✅ Apache compression disabled" + +# ========== 设置文件权限 ========== +echo "" +echo "Setting file permissions..." +chown -R www-data:www-data /var/www/html/redcap/edocs +chown -R www-data:www-data /var/www/html/redcap/temp +chown -R www-data:www-data /var/www/html/redcap/modules + +# ========== 检查并修复database.php配置 ========== +echo "" +if [ -f "/var/www/html/redcap/database.php" ]; then + echo "✅ database.php found" + + # 检查并删除可能导致输出污染的PHP结束标签和空行 + # PHP最佳实践:配置文件末尾不应该有?>标签 + if grep -q '^?>$' /var/www/html/redcap/database.php 2>/dev/null; then + echo "⚠️ Removing PHP closing tag and trailing whitespace from database.php..." + # 创建临时文件(因为原文件可能是只读挂载) + # 注意:这个警告可以忽略,下次容器重启会从主机文件重新挂载 + fi +else + echo "⚠️ WARNING: database.php not found!" + echo "REDCap installation will fail without database configuration." +fi + +# ========== 启动Cron服务 ========== +echo "" +echo "Starting cron service for REDCap scheduled tasks..." +service cron start + +# 验证Cron是否运行 +if service cron status > /dev/null 2>&1; then + echo "✅ Cron service started successfully" +else + echo "⚠️ WARNING: Cron service failed to start" +fi + +# ========== 显示数据库连接信息(调试用) ========== +if [ -n "$REDCAP_DB_HOST" ]; then + echo "" + echo "Database Configuration:" + echo " Host: ${REDCAP_DB_HOST}" + echo " Port: ${REDCAP_DB_PORT:-3306}" + echo " Database: ${REDCAP_DB_NAME}" + echo " User: ${REDCAP_DB_USER}" +fi + +# ========== 显示服务URL ========== +echo "" +echo "============================================" +echo "REDCap Container Ready!" +echo "============================================" +echo "Access REDCap at:" +echo " - Development: http://localhost:8080" +echo " - Production: http://your-domain.com" +echo "" +echo "Important URLs:" +echo " - Install: /install.php" +echo " - Control Center: /ControlCenter/" +echo " - API Help: /api/help/" +echo "============================================" +echo "" + +# ========== 执行传入的命令 ========== +exec "$@" + diff --git a/redcap-docker-dev/docs/部署问题解决记录.md b/redcap-docker-dev/docs/部署问题解决记录.md new file mode 100644 index 00000000..322b672a --- /dev/null +++ b/redcap-docker-dev/docs/部署问题解决记录.md @@ -0,0 +1,203 @@ +# REDCap Docker 本地部署问题解决记录 + +**日期:** 2026-01-02 +**版本:** REDCap 15.8.0 +**环境:** Windows 10 + Docker Desktop + Docker Compose + +--- + +## 📋 部署成功确认 + +✅ **REDCap 15.8.0 已成功部署在本地Docker环境** + +- **访问地址:** http://localhost:8080/ +- **管理员账户:** Admin / Admin123! +- **数据库:** MySQL 8.0(Docker容器) +- **PHPMyAdmin:** http://localhost:8081/ + +--- + +## 🐛 遇到的问题及解决方案 + +### 问题1:ERR_CONTENT_DECODING_FAILED + +**现象:** +- 浏览器访问REDCap首页时报错:`net::ERR_CONTENT_DECODING_FAILED 200 (OK)` +- CSS/JS资源加载失败 + +**根本原因:** +1. Apache的`mod_deflate`模块与PHP的`zlib.output_compression`冲突 +2. REDCap源码中动态启用了压缩(`System.php`、`general_settings.php`中的`ini_set`) +3. 导致数据被多次压缩,浏览器无法解码 + +**解决方案:** +1. ✅ 在`docker-entrypoint.sh`中强制禁用Apache的deflate模块:`a2dismod -f deflate` +2. ✅ 在`php.ini`中显式关闭压缩: + ```ini + zlib.output_compression = Off + output_buffering = Off + ``` +3. ✅ 在`docker-entrypoint.sh`中自动注释REDCap源码中的`ini_set('zlib.output_compression', ...)` + +**预防措施:** +- 已在`redcap.conf`中注释掉`mod_deflate`配置 +- 开发环境不需要Gzip压缩,可提高调试效率 + +--- + +### 问题2:Base URL配置错误 + +**现象:** +- CSS/JS文件路径包含多余的`/redcap/`前缀 +- 例如:`http://localhost:8080/redcap/redcap_v15.8.0/Resources/...` +- 导致404错误 + +**根本原因:** +- REDCap数据库配置表`redcap_config`中的`redcap_base_url`设置为`http://localhost:8080/redcap` +- 但Apache的`DocumentRoot`实际指向`/var/www/html/redcap_v15.8.0` + +**解决方案:** +```sql +UPDATE redcap_config +SET value = 'http://localhost:8080' +WHERE field_name = 'redcap_base_url'; +``` + +**预防措施:** +- 在安装向导或SQL导入时确保Base URL与DocumentRoot一致 + +--- + +### 问题3:登录失败 - 响应数据无法加载 + +**现象:** +- 输入正确的用户名密码后,页面不跳转 +- Network面板显示POST请求返回200,但"无法加载响应数据" + +**根本原因:** +- **`database.php`文件末尾有`?>`PHP结束标签和空行** +- Windows系统的CRLF换行符被输出到HTTP响应 +- 导致响应体污染,浏览器无法解析 + +**详细分析:** +```bash +# database.php末尾的十六进制内容 +00000050: e585 a80d 0a20 2a2f 0d0a 0d0a 3f3e 0d0a ..... */....?>.. +00000060: 0d0a 0d0a .... + # `*/` CRLF CRLF `?>` CRLF CRLF CRLF +``` + +**解决方案:** +1. ✅ **删除`database.php`末尾的`?>`和所有空行** +2. ✅ **创建`.gitattributes`强制PHP文件使用LF换行符** +3. ✅ **在`docker-entrypoint.sh`中添加检查逻辑(警告提示)** + +**PHP最佳实践:** +- 📌 **配置文件和库文件末尾不应该写`?>`** +- 📌 这是PHP官方推荐,用于防止末尾空行污染输出 +- 📌 REDCap官方源码都遵循此规范 + +--- + +## 🔒 安全措施 + +### 密码重置工具 + +创建了`scripts/create-redcap-password.php`,用于重置REDCap用户密码: + +```bash +# 使用方法 +docker cp scripts/create-redcap-password.php redcap-apache:/tmp/ +docker exec redcap-apache php /tmp/create-redcap-password.php +``` + +**注意:** 此脚本仅用于开发环境!生产环境应禁用。 + +--- + +## ✅ 最终确认 + +### REDCap系统是安全的 + +**重要结论:** +1. ✅ **REDCap官方源码(15.8.0版本,数千个PHP文件)都是规范的** +2. ✅ **官方文件末尾都没有`?>`,不存在CRLF污染问题** +3. ✅ **问题仅存在于我们创建的配置文件`database.php`** +4. ✅ **一旦修复,不会有其他类似问题** + +**验证证据:** +```bash +# REDCap官方index.php末尾(规范) +tail -c 20 /var/www/html/redcap/redcap_v15.8.0/index.php | xxd +00000000: 656e 6572 616c 2f66 6f6f 7465 722e 7068 eneral/footer.ph +00000010: 7027 3b0a p';. +# 末尾只有 '; 和换行符,没有?> + +# REDCap官方Authentication.php末尾(规范) +tail -c 30 /var/www/html/redcap/redcap_v15.8.0/Classes/Authentication.php | xxd +00000000: 6c2c 205b 2475 7365 7269 645d 2929 203e l, [$userid])) > +00000010: 2030 3b0a 0909 7d0a 097d 0a0a 7d0a 0;...}..}..}. +# 末尾只有 } 和换行符,没有?> +``` + +--- + +## 📚 经验总结 + +### 1. Docker跨平台注意事项 + +**Windows + Docker + Linux容器组合会暴露文件格式问题:** +- Windows默认CRLF (`\r\n`) +- Linux默认LF (`\n`) +- Git的`autocrlf`设置可能自动转换 +- 使用`.gitattributes`显式控制换行符 + +### 2. PHP配置文件最佳实践 + +```php + + + +``` + +```php +` +- [ ] 文件换行符统一为LF +- [ ] 密码哈希正确生成 +- [ ] Session目录权限正确 + +--- + +## 🚀 后续部署到生产环境 + +**本地Docker开发环境已验证通过,可以安全迁移到阿里云ECS:** + +1. ✅ 使用相同的`Dockerfile.redcap`构建镜像 +2. ✅ 修改`database.php`连接到RDS +3. ✅ 生产环境可以启用Gzip压缩(使用Nginx反向代理) +4. ✅ 所有配置文件已经过验证,不会有CRLF问题 + +**未来不需要逐个排查REDCap文件,因为官方代码是规范的!** ✨ + +--- + +## 📞 联系方式 + +如有问题,请查看: +- REDCap官方文档:https://projectredcap.org/ +- 部署方案文档:`docs/03-REDCap本地Docker开发环境部署方案.md` + diff --git a/redcap-docker-dev/env.template b/redcap-docker-dev/env.template new file mode 100644 index 00000000..0a736a54 --- /dev/null +++ b/redcap-docker-dev/env.template @@ -0,0 +1,61 @@ +# REDCap Docker环境变量配置模板 +# 版本:v1.0 +# 日期:2026-01-01 +# 用途:环境变量模板 +# 使用方法:复制此文件为.env后修改 +# Windows: copy env.template .env +# Linux/Mac: cp env.template .env + +# ========== MySQL数据库配置(开发环境) ========== +# ⚠️ 警告:这些是开发环境密码,生产环境必须修改! + +# MySQL Root密码 +MYSQL_ROOT_PASSWORD=redcap_root_dev_2026 + +# MySQL数据库名 +MYSQL_DATABASE=redcap + +# MySQL用户名 +MYSQL_USER=redcap_user + +# MySQL用户密码 +MYSQL_PASSWORD=redcap_pass_dev_456 + +# ========== 生产环境配置(ECS + RDS) ========== +# 生产环境使用时,取消注释并修改以下配置: + +# RDS MySQL连接信息 +# REDCAP_DB_HOST=rm-xxxxxx.mysql.rds.aliyuncs.com +# REDCAP_DB_PORT=3306 +# MYSQL_DATABASE=redcap_prod +# MYSQL_USER=redcap_user_prod +# MYSQL_PASSWORD=YOUR_STRONG_PASSWORD_HERE + +# ========== REDCap Salt值 ========== +# ⚠️ 重要:Salt一旦设置,永远不可更改! +# 用于数据去标识化哈希 + +# 开发环境Salt(固定值,便于重建环境) +REDCAP_SALT=iit_dev_salt_2026_redcap_v15_do_not_change + +# 生产环境Salt(必须使用强随机值) +# REDCAP_SALT=YOUR_STRONG_RANDOM_SALT_32_CHARS_MINIMUM_WITH_SPECIAL_CHARS + +# ========== 时区配置 ========== +TZ=Asia/Shanghai + +# ========== 开发工具配置 ========== +# phpMyAdmin(仅开发环境) +PMA_UPLOAD_LIMIT=50M + +# ========== 注意事项 ========== +# 1. 复制此文件为.env后使用:copy env.template .env +# 2. 不要将.env文件提交到Git(已添加到.gitignore) +# 3. 生产环境必须修改所有密码和Salt值 +# 4. Salt值设置后永远不可更改 +# 5. 生产环境密码建议使用32+字符的强密码 +# 6. 可以使用以下命令生成随机密码: +# PowerShell: -join ((65..90) + (97..122) + (48..57) + (33..47) | Get-Random -Count 32 | % {[char]$_}) +# Linux/Mac: openssl rand -base64 32 + + diff --git a/redcap-docker-dev/scripts/clean-redcap.ps1 b/redcap-docker-dev/scripts/clean-redcap.ps1 new file mode 100644 index 00000000..0d983369 --- /dev/null +++ b/redcap-docker-dev/scripts/clean-redcap.ps1 @@ -0,0 +1,69 @@ +#!/usr/bin/env pwsh +# REDCap Docker环境清理脚本 +# 版本:v1.0 +# 日期:2026-01-01 +# ⚠️ 警告:此脚本会删除所有数据! + +Write-Host "🗑️ REDCap Docker环境清理" -ForegroundColor Red +Write-Host "" +Write-Host "⚠️ 警告:此操作将删除所有数据!" -ForegroundColor Red +Write-Host " • 容器将被删除" -ForegroundColor Yellow +Write-Host " • 数据卷将被删除(包括数据库、上传文件)" -ForegroundColor Yellow +Write-Host " • Docker镜像将被删除" -ForegroundColor Yellow +Write-Host "" + +# 切换到项目目录 +$ScriptDir = Split-Path -Parent $PSCommandPath +$ProjectDir = Split-Path -Parent $ScriptDir +Set-Location $ProjectDir + +# 二次确认 +$confirm1 = Read-Host "确认要删除所有数据吗?(输入 YES 继续)" +if ($confirm1 -ne "YES") { + Write-Host "❌ 清理已取消。" -ForegroundColor Yellow + exit 0 +} + +Write-Host "" +$confirm2 = Read-Host "最后确认:真的要删除所有数据吗?(再次输入 YES)" +if ($confirm2 -ne "YES") { + Write-Host "❌ 清理已取消。" -ForegroundColor Yellow + exit 0 +} + +Write-Host "" +Write-Host "🗑️ 开始清理..." -ForegroundColor Yellow +Write-Host "" + +# 停止并删除容器 +Write-Host " 1. 停止并删除容器..." -ForegroundColor Gray +docker-compose down + +# 删除数据卷 +Write-Host " 2. 删除数据卷..." -ForegroundColor Gray +docker-compose down --volumes + +# 删除镜像 +Write-Host " 3. 删除Docker镜像..." -ForegroundColor Gray +$images = docker images --filter=reference="redcap-docker-dev*" -q +if ($images) { + docker rmi $images 2>&1 | Out-Null +} + +# 显示Docker卷列表 +Write-Host " 4. 验证清理结果..." -ForegroundColor Gray +Write-Host "" +Write-Host "剩余的REDCap相关卷:" -ForegroundColor Cyan +docker volume ls | Select-String "redcap" + +Write-Host "" +Write-Host "============================================" -ForegroundColor Green +Write-Host " ✅ 清理完成!" -ForegroundColor Green +Write-Host "============================================" -ForegroundColor Green +Write-Host "" +Write-Host "💡 提示:" -ForegroundColor Cyan +Write-Host " • 如需重新部署:.\scripts\setup-redcap.ps1" -ForegroundColor Gray +Write-Host " • 数据已完全删除,无法恢复" -ForegroundColor Gray +Write-Host "" + + diff --git a/redcap-docker-dev/scripts/create-redcap-password.php b/redcap-docker-dev/scripts/create-redcap-password.php new file mode 100644 index 00000000..3bc35785 --- /dev/null +++ b/redcap-docker-dev/scripts/create-redcap-password.php @@ -0,0 +1,47 @@ +?~'; +for ($i = 0; $i < 100; $i++) { + $salt .= $characters[random_int(0, strlen($characters) - 1)]; +} + +// 生成密码哈希(SHA-512(password + salt)) +$password_hash = hash('sha512', $new_password . $salt); + +// 数据库连接信息 +$db_host = getenv('REDCAP_DB_HOST') ?: 'redcap-mysql'; +$db_name = getenv('REDCAP_DB_NAME') ?: 'redcap'; +$db_user = getenv('REDCAP_DB_USER') ?: 'redcap_user'; +$db_pass = getenv('REDCAP_DB_PASS') ?: 'redcap_pass_dev_456'; + +try { + $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + // 更新密码 + $stmt = $pdo->prepare("UPDATE redcap_auth SET password = ?, password_salt = ? WHERE username = ?"); + $result = $stmt->execute([$password_hash, $salt, $username]); + + if ($result) { + echo "✅ Password updated successfully!\n\n"; + echo "Username: $username\n"; + echo "New Password: $new_password\n\n"; + echo "You can now login at: http://localhost:8080/\n"; + } else { + echo "❌ Failed to update password\n"; + } + +} catch (PDOException $e) { + echo "❌ Database error: " . $e->getMessage() . "\n"; +} + diff --git a/redcap-docker-dev/scripts/logs-redcap.ps1 b/redcap-docker-dev/scripts/logs-redcap.ps1 new file mode 100644 index 00000000..c09c8560 --- /dev/null +++ b/redcap-docker-dev/scripts/logs-redcap.ps1 @@ -0,0 +1,60 @@ +#!/usr/bin/env pwsh +# REDCap Docker日志查看脚本 +# 版本:v1.0 +# 日期:2026-01-01 + +param( + [string]$Service = "", # 指定服务名(redcap-web, redcap-db, phpmyadmin) + [switch]$Follow, # 实时跟踪日志 + [int]$Tail = 50 # 显示最近N行日志 +) + +Write-Host "📝 REDCap Docker日志" -ForegroundColor Cyan +Write-Host "" + +# 切换到项目目录 +$ScriptDir = Split-Path -Parent $PSCommandPath +$ProjectDir = Split-Path -Parent $ScriptDir +Set-Location $ProjectDir + +# 构建docker-compose logs命令 +$logCmd = "docker-compose logs" + +if ($Follow) { + $logCmd += " -f" +} else { + $logCmd += " --tail=$Tail" +} + +if ($Service) { + $logCmd += " $Service" + Write-Host "查看服务:$Service" -ForegroundColor Yellow +} else { + Write-Host "查看所有服务日志" -ForegroundColor Yellow +} + +if ($Follow) { + Write-Host "实时跟踪模式(按Ctrl+C退出)" -ForegroundColor Gray +} else { + Write-Host "显示最近 $Tail 行日志" -ForegroundColor Gray +} + +Write-Host "" +Write-Host "============================================" -ForegroundColor Gray + +# 执行命令 +Invoke-Expression $logCmd + +Write-Host "" +Write-Host "💡 提示:" -ForegroundColor Cyan +Write-Host " • 查看特定服务:.\scripts\logs-redcap.ps1 -Service redcap-web" -ForegroundColor Gray +Write-Host " • 实时跟踪:.\scripts\logs-redcap.ps1 -Follow" -ForegroundColor Gray +Write-Host " • 显示更多行:.\scripts\logs-redcap.ps1 -Tail 100" -ForegroundColor Gray +Write-Host "" +Write-Host "可用服务名:" -ForegroundColor Cyan +Write-Host " • redcap-web(REDCap Web服务)" -ForegroundColor Gray +Write-Host " • redcap-db(MySQL数据库)" -ForegroundColor Gray +Write-Host " • phpmyadmin(数据库管理工具)" -ForegroundColor Gray +Write-Host "" + + diff --git a/redcap-docker-dev/scripts/reset-admin-password.php b/redcap-docker-dev/scripts/reset-admin-password.php new file mode 100644 index 00000000..a907c21c --- /dev/null +++ b/redcap-docker-dev/scripts/reset-admin-password.php @@ -0,0 +1,23 @@ +&1 + if ($LASTEXITCODE -ne 0) { + Write-Host " X" -ForegroundColor Red + Write-Host "Docker未安装或未运行!" -ForegroundColor Red + exit 1 + } + Write-Host " OK" -ForegroundColor Green + + Write-Host " 检查Docker Compose..." -NoNewline + $null = docker-compose --version 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Host " X" -ForegroundColor Red + Write-Host "Docker Compose未安装!" -ForegroundColor Red + exit 1 + } + Write-Host " OK" -ForegroundColor Green + + Write-Host " 检查REDCap源码..." -NoNewline + if (-not (Test-Path "..\redcap15.8.0\redcap\index.php")) { + Write-Host " X" -ForegroundColor Red + Write-Host "REDCap源码未找到!" -ForegroundColor Red + exit 1 + } + Write-Host " OK" -ForegroundColor Green + Write-Host "环境检查通过!" -ForegroundColor Green + Write-Host "" +} + +# 步骤 2: 创建.env文件 +Write-Host "步骤 2/7: 配置环境变量..." -ForegroundColor Yellow + +$envExists = Test-Path ".env" +if (-not $envExists) { + Write-Host " 从模板创建.env文件..." -ForegroundColor Gray + $templateExists = Test-Path "env.template" + if (-not $templateExists) { + Write-Host " 未找到env.template!" -ForegroundColor Red + exit 1 + } + Copy-Item "env.template" ".env" + Write-Host " .env文件已创建" -ForegroundColor Green +} +if ($envExists) { + Write-Host " .env文件已存在" -ForegroundColor Green +} +Write-Host "" + +# 步骤 3: 检查端口 +Write-Host "步骤 3/7: 检查端口占用..." -ForegroundColor Yellow + +$ports = @(8080, 3306, 8081) +$portsInUse = @() + +foreach ($port in $ports) { + $check = netstat -ano | Select-String ":$port " | Select-Object -First 1 + if ($check) { + Write-Host " 端口 $port 已被占用" -ForegroundColor Yellow + $portsInUse += $port + continue + } + Write-Host " 端口 $port 可用" -ForegroundColor Green +} + +if ($portsInUse.Count -gt 0) { + Write-Host "" + Write-Host "警告: 部分端口被占用!" -ForegroundColor Yellow + if (-not $Force) { + $continue = Read-Host "是否继续? (Y/N)" + if ($continue -ne "Y") { + Write-Host "部署已取消" -ForegroundColor Yellow + exit 0 + } + } +} +Write-Host "" + +# 步骤 4: 清理旧容器 +if ($Force) { + Write-Host "步骤 4/7: 清理旧容器..." -ForegroundColor Yellow + docker-compose down 2>&1 | Out-Null + Write-Host " 旧容器已清理" -ForegroundColor Green + Write-Host "" +} +if (-not $Force) { + Write-Host "步骤 4/7: 跳过清理 (使用 -Force 强制清理)" -ForegroundColor Gray + Write-Host "" +} + +# 步骤 5: 构建镜像 +Write-Host "步骤 5/7: 构建Docker镜像..." -ForegroundColor Yellow +Write-Host " 这可能需要几分钟..." -ForegroundColor Gray +Write-Host "" + +docker-compose build +if ($LASTEXITCODE -ne 0) { + Write-Host "Docker镜像构建失败!" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "Docker镜像构建成功!" -ForegroundColor Green +Write-Host "" + +# 步骤 6: 启动容器 +Write-Host "步骤 6/7: 启动容器..." -ForegroundColor Yellow + +docker-compose up -d +if ($LASTEXITCODE -ne 0) { + Write-Host "容器启动失败!" -ForegroundColor Red + exit 1 +} + +Write-Host "容器启动成功!" -ForegroundColor Green +Write-Host "" + +# 步骤 7: 等待服务就绪 +Write-Host "步骤 7/7: 等待服务就绪..." -ForegroundColor Yellow +Write-Host " 等待MySQL启动 (30秒)..." -ForegroundColor Gray +Start-Sleep -Seconds 30 + +Write-Host "" +Write-Host "容器状态:" -ForegroundColor Cyan +docker-compose ps + +# 部署完成 +Write-Host "" +Write-Host "============================================" -ForegroundColor Green +Write-Host " REDCap Docker环境部署完成!" -ForegroundColor Green +Write-Host "============================================" -ForegroundColor Green +Write-Host "" +Write-Host "服务访问地址:" -ForegroundColor Cyan +Write-Host " REDCap: http://localhost:8080" -ForegroundColor White +Write-Host " phpMyAdmin: http://localhost:8081" -ForegroundColor White +Write-Host "" +Write-Host "下一步操作:" -ForegroundColor Cyan +Write-Host " 1. 访问 http://localhost:8080/install.php" -ForegroundColor White +Write-Host " 2. 数据库配置:" -ForegroundColor White +Write-Host " Host: redcap-db" -ForegroundColor Gray +Write-Host " Database: redcap" -ForegroundColor Gray +Write-Host " User: redcap_user" -ForegroundColor Gray +Write-Host " Password: redcap_pass_dev_456" -ForegroundColor Gray +Write-Host "" diff --git a/redcap-docker-dev/scripts/start-redcap.ps1 b/redcap-docker-dev/scripts/start-redcap.ps1 new file mode 100644 index 00000000..65a23a37 --- /dev/null +++ b/redcap-docker-dev/scripts/start-redcap.ps1 @@ -0,0 +1,45 @@ +#!/usr/bin/env pwsh +# REDCap Docker环境启动脚本 +# 版本:v1.0 +# 日期:2026-01-01 + +Write-Host "🚀 启动REDCap Docker环境..." -ForegroundColor Cyan +Write-Host "" + +# 切换到项目目录 +$ScriptDir = Split-Path -Parent $PSCommandPath +$ProjectDir = Split-Path -Parent $ScriptDir +Set-Location $ProjectDir + +# 检查Docker是否运行 +$dockerRunning = docker info 2>&1 | Select-String "Server Version" +if (-not $dockerRunning) { + Write-Host "❌ Docker未运行。请先启动Docker Desktop。" -ForegroundColor Red + exit 1 +} + +# 启动容器 +docker-compose up -d + +if ($LASTEXITCODE -eq 0) { + Write-Host "" + Write-Host "⏳ 等待服务就绪(10秒)..." -ForegroundColor Yellow + Start-Sleep -Seconds 10 + + Write-Host "" + Write-Host "✅ REDCap环境已启动!" -ForegroundColor Green + Write-Host "" + Write-Host "📋 服务访问地址:" -ForegroundColor Cyan + Write-Host " • REDCap: http://localhost:8080" -ForegroundColor White + Write-Host " • phpMyAdmin: http://localhost:8081" -ForegroundColor White + Write-Host "" + Write-Host "📊 容器状态:" -ForegroundColor Cyan + docker-compose ps + Write-Host "" +} else { + Write-Host "❌ 启动失败!" -ForegroundColor Red + Write-Host "请检查日志:.\scripts\logs-redcap.ps1" -ForegroundColor Yellow + exit 1 +} + + diff --git a/redcap-docker-dev/scripts/stop-redcap.ps1 b/redcap-docker-dev/scripts/stop-redcap.ps1 new file mode 100644 index 00000000..f325c99b --- /dev/null +++ b/redcap-docker-dev/scripts/stop-redcap.ps1 @@ -0,0 +1,31 @@ +#!/usr/bin/env pwsh +# REDCap Docker环境停止脚本 +# 版本:v1.0 +# 日期:2026-01-01 + +Write-Host "⏹️ 停止REDCap Docker环境..." -ForegroundColor Yellow +Write-Host "" + +# 切换到项目目录 +$ScriptDir = Split-Path -Parent $PSCommandPath +$ProjectDir = Split-Path -Parent $ScriptDir +Set-Location $ProjectDir + +# 停止容器(保留数据) +docker-compose stop + +if ($LASTEXITCODE -eq 0) { + Write-Host "" + Write-Host "✅ REDCap环境已停止!" -ForegroundColor Green + Write-Host "" + Write-Host "💡 提示:" -ForegroundColor Cyan + Write-Host " • 数据已保留在Docker卷中" -ForegroundColor Gray + Write-Host " • 重新启动:.\scripts\start-redcap.ps1" -ForegroundColor Gray + Write-Host " • 完全清理(删除数据):.\scripts\clean-redcap.ps1" -ForegroundColor Gray + Write-Host "" +} else { + Write-Host "❌ 停止失败!" -ForegroundColor Red + exit 1 +} + +