#!/bin/bash # DMS合规性测试工具 - Docker Compose版本部署包创建脚本(简化版) # 使用Alpine Linux + 多阶段构建 + Docker Compose管理 # 自动检测当前平台架构 set -e # 配置变量 EXPORT_DIR="dms-compliance-compose-$(date +%Y%m%d-%H%M%S)" IMAGE_NAME="compliance-dms-mini" ARCHIVE_NAME="$EXPORT_DIR.tar.gz" echo "=== DMS合规性测试工具 Docker Compose版本部署包创建脚本(简化版) ===" echo "[信息] 使用Docker Compose管理,完全兼容原版架构" echo "[信息] 自动检测当前平台架构" # 检查Docker是否运行 if ! docker info >/dev/null 2>&1; then echo "[错误] Docker未运行或无法访问" exit 1 fi # 检测当前平台架构 CURRENT_ARCH=$(docker version --format '{{.Server.Arch}}' 2>/dev/null || uname -m) case "$CURRENT_ARCH" in x86_64|amd64) TARGET_PLATFORM="linux/amd64" ARCH_NAME="AMD64 (x86_64)" ;; aarch64|arm64) TARGET_PLATFORM="linux/arm64" ARCH_NAME="ARM64 (aarch64)" ;; *) TARGET_PLATFORM="linux/amd64" # 默认使用amd64 ARCH_NAME="AMD64 (x86_64) - 默认" echo "[警告] 未识别的架构 $CURRENT_ARCH,使用默认的 amd64" ;; esac echo "[信息] 检测到架构: $ARCH_NAME" echo "[信息] 目标平台: $TARGET_PLATFORM" # 创建导出目录 echo "[信息] 创建导出目录: $EXPORT_DIR" rm -rf "$EXPORT_DIR" mkdir -p "$EXPORT_DIR" # 1. 创建临时构建目录,只包含必要文件 echo "[信息] 创建临时构建目录..." TEMP_BUILD_DIR=$(mktemp -d) trap "rm -rf $TEMP_BUILD_DIR" EXIT # 白名单:只复制必要的文件 echo "[信息] 复制必要文件(超精简模式)..." mkdir -p "$TEMP_BUILD_DIR"/{ddms_compliance_suite,custom_stages,custom_testcases,templates,static,assets} # 只复制核心Python文件 echo "[信息] 复制核心Python文件..." for file in api_server.py history_viewer.py flask_app.py; do [ -f "$file" ] && cp "$file" "$TEMP_BUILD_DIR/" done # 复制核心目录(排除缓存和临时文件) echo "[信息] 复制核心目录..." rsync -av --exclude='__pycache__' --exclude='*.pyc' --exclude='*.log' ddms_compliance_suite/ "$TEMP_BUILD_DIR/ddms_compliance_suite/" rsync -av --exclude='__pycache__' --exclude='*.pyc' custom_stages/ "$TEMP_BUILD_DIR/custom_stages/" rsync -av --exclude='__pycache__' --exclude='*.pyc' custom_testcases/ "$TEMP_BUILD_DIR/custom_testcases/" # 确保templates目录结构正确 echo "[信息] 复制模板和静态文件..." rsync -av templates/ "$TEMP_BUILD_DIR/templates/" rsync -av static/ "$TEMP_BUILD_DIR/static/" rsync -av assets/ "$TEMP_BUILD_DIR/assets/" # 验证templates目录内容 echo "[信息] 验证templates目录: $(ls "$TEMP_BUILD_DIR/templates/" 2>/dev/null | wc -l) 个文件" echo "[信息] templates文件列表: $(ls "$TEMP_BUILD_DIR/templates/" 2>/dev/null | tr '\n' ' ')" # 复制完整的requirements.txt echo "[信息] 复制完整的requirements.txt..." cp requirements.txt "$TEMP_BUILD_DIR/" # 创建超轻量级Dockerfile echo "[信息] 创建超轻量级Dockerfile..." # 首先尝试创建优化的多阶段构建Dockerfile cat > "$TEMP_BUILD_DIR/Dockerfile" << 'EOF' # 多阶段构建:第一阶段安装依赖 FROM python:3.9-alpine AS builder # 更新包索引并安装构建依赖 RUN apk update && \ apk add --no-cache \ gcc \ musl-dev \ linux-headers \ libffi-dev \ openssl-dev \ cargo \ rust && \ rm -rf /var/cache/apk/* # 设置工作目录 WORKDIR /app # 复制requirements并安装Python依赖 COPY requirements.txt . # 升级pip并安装依赖 RUN pip install --upgrade pip setuptools wheel && \ pip install --no-cache-dir --user -r requirements.txt # 第二阶段:运行时镜像 FROM python:3.9-alpine # 安装运行时依赖 RUN apk update && \ apk add --no-cache \ supervisor \ curl \ bash && \ rm -rf /var/cache/apk/* # 从构建阶段复制Python包 COPY --from=builder /root/.local /root/.local # 设置工作目录 WORKDIR /app # 复制应用代码 COPY . . # 创建supervisor配置 RUN mkdir -p /etc/supervisor/conf.d COPY supervisord.conf /etc/supervisor/conf.d/ # 创建日志目录 RUN mkdir -p /var/log/supervisor /app/logs /app/test_reports /app/uploads # 设置环境变量 ENV PATH=/root/.local/bin:$PATH ENV PYTHONPATH=/app ENV FLASK_ENV=production ENV PYTHONUNBUFFERED=1 # 暴露端口(两个服务的端口) EXPOSE 5050 5051 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:5050/ || exit 1 # 启动supervisor CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] EOF # 创建备用的简化Dockerfile(如果多阶段构建失败) cat > "$TEMP_BUILD_DIR/Dockerfile.simple" << 'EOF' # 简化版本:单阶段构建 FROM python:3.9-alpine # 安装所有必要的依赖 RUN apk update && \ apk add --no-cache \ gcc \ musl-dev \ linux-headers \ libffi-dev \ openssl-dev \ supervisor \ curl \ bash && \ rm -rf /var/cache/apk/* # 设置工作目录 WORKDIR /app # 复制应用代码 COPY . . # 安装Python依赖 RUN pip install --upgrade pip setuptools wheel && \ pip install --no-cache-dir -r requirements.txt # 创建supervisor配置目录 RUN mkdir -p /etc/supervisor/conf.d COPY supervisord.conf /etc/supervisor/conf.d/ # 创建必要目录 RUN mkdir -p /var/log/supervisor /app/logs /app/test_reports /app/uploads # 设置环境变量 ENV PYTHONPATH=/app ENV FLASK_ENV=production ENV PYTHONUNBUFFERED=1 # 暴露端口 EXPOSE 5050 5051 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:5050/ || exit 1 # 启动supervisor CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] EOF # 创建supervisor配置 echo "[信息] 创建supervisor配置..." cat > "$TEMP_BUILD_DIR/supervisord.conf" << 'EOF' [supervisord] nodaemon=true logfile=/var/log/supervisor/supervisord.log pidfile=/var/run/supervisord.pid childlogdir=/var/log/supervisor logfile_maxbytes=50MB logfile_backups=10 loglevel=info [unix_http_server] file=/tmp/supervisor.sock chmod=0700 [supervisorctl] serverurl=unix:///tmp/supervisor.sock [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface # DMS API服务器 (主服务) [program:api_server] command=python api_server.py directory=/app autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/supervisor/api_server.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=5 environment=PYTHONPATH="/app",PYTHONUNBUFFERED="1" # 历史查看器服务 [program:history_viewer] command=python history_viewer.py directory=/app autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/supervisor/history_viewer.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=5 environment=PYTHONPATH="/app",PYTHONUNBUFFERED="1" # 进程组配置 [group:dms_services] programs=api_server,history_viewer priority=999 EOF # 显示构建目录大小 echo "[信息] 临时构建目录大小: $(du -sh "$TEMP_BUILD_DIR" | cut -f1)" # 2. 构建Docker镜像 echo "[信息] 构建超轻量Docker镜像 ($TARGET_PLATFORM)..." cd "$TEMP_BUILD_DIR" # 尝试构建,首先使用多阶段构建,失败则使用简化构建 if docker build --platform "$TARGET_PLATFORM" -t "$IMAGE_NAME:latest" .; then echo "[成功] Docker构建完成(多阶段构建)" else echo "[警告] 多阶段构建失败,尝试简化构建..." if docker build --platform "$TARGET_PLATFORM" -t "$IMAGE_NAME:latest" -f Dockerfile.simple .; then echo "[成功] Docker构建完成(简化构建)" else echo "[错误] 所有构建方式都失败" exit 1 fi fi cd - > /dev/null # 3. 导出Docker镜像 echo "[信息] 导出Docker镜像..." docker save "$IMAGE_NAME:latest" | gzip > "$EXPORT_DIR/docker-image.tar.gz" # 4. 创建docker-compose.yml echo "[信息] 创建docker-compose.yml..." cat > "$EXPORT_DIR/docker-compose.yml" << 'EOF' version: '3.8' services: dms-compliance-tool: image: compliance-dms-mini:latest container_name: dms-compliance-mini ports: - "5050:5050" # API服务器端口 - "5051:5051" # 历史查看器端口 volumes: # 持久化测试报告 - ./test_reports:/app/test_reports # 持久化上传文件 - ./uploads:/app/uploads # 持久化日志 - ./logs:/app/logs # 如果需要自定义配置文件 - ./config:/app/config:ro environment: - FLASK_ENV=production - PYTHONUNBUFFERED=1 - TZ=Asia/Shanghai restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5050/"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - dms-network networks: dms-network: driver: bridge volumes: test_reports: uploads: logs: EOF # 5. 创建部署脚本 echo "[信息] 创建部署脚本..." cat > "$EXPORT_DIR/deploy.sh" << 'EOF' #!/bin/bash # DMS合规性测试工具 - Docker Compose版本部署脚本 set -e echo "=== DMS合规性测试工具 Docker Compose版本部署 ===" # 检查Docker和Docker Compose if ! docker info >/dev/null 2>&1; then echo "[错误] Docker未运行" exit 1 fi if ! command -v docker-compose >/dev/null 2>&1 && ! docker compose version >/dev/null 2>&1; then echo "[错误] Docker Compose未安装" echo "请安装Docker Compose或使用Docker Desktop" exit 1 fi # 创建必要的目录 echo "[信息] 创建数据目录..." mkdir -p test_reports uploads logs config # 加载镜像 echo "[信息] 加载Docker镜像..." docker load < docker-image.tar.gz # 停止现有服务 echo "[信息] 停止现有服务..." docker-compose down 2>/dev/null || docker compose down 2>/dev/null || true # 启动服务 echo "[信息] 启动服务..." if command -v docker-compose >/dev/null 2>&1; then docker-compose up -d else docker compose up -d fi echo "[成功] 部署完成!" echo "访问地址: http://localhost:5050 (API服务器)" echo "访问地址: http://localhost:5051 (历史查看器)" echo "" echo "管理命令:" echo "- 查看状态: docker-compose ps" echo "- 查看日志: docker-compose logs" echo "- 停止服务: docker-compose down" echo "- 重启服务: docker-compose restart" echo "" echo "数据目录:" echo "- 测试报告: $(pwd)/test_reports" echo "- 上传文件: $(pwd)/uploads" echo "- 日志文件: $(pwd)/logs" echo "- 配置文件: $(pwd)/config" EOF chmod +x "$EXPORT_DIR/deploy.sh" # 6. 创建README echo "[信息] 创建README..." cat > "$EXPORT_DIR/README.md" << 'EOF' # DMS合规性测试工具 - Docker Compose版本(简化版) ## 特点 - 基于Alpine Linux,镜像体积极小(约300MB) - 多阶段构建,优化层结构 - 完全兼容原版架构(5050+5051端口) - 使用Docker Compose管理服务 - 支持数据持久化和健康检查 - 自动检测当前平台架构,无需手动选择 ## 部署方法 1. 解压部署包 2. 运行部署脚本: ```bash ./deploy.sh ``` 3. 访问服务: - API服务器: http://localhost:5050 - 历史查看器: http://localhost:5051 ## 管理命令 - 查看服务状态:`docker-compose ps` - 查看日志:`docker-compose logs` - 停止服务:`docker-compose down` - 重启服务:`docker-compose restart` - 查看实时日志:`docker-compose logs -f` ## 文件说明 - `docker-image.tar.gz` - Docker镜像文件 - `docker-compose.yml` - Docker Compose配置文件 - `deploy.sh` - 一键部署脚本 - `README.md` - 说明文档 ## 数据持久化 所有重要数据都会持久化到本地目录: - `test_reports/` - 测试报告 - `uploads/` - 上传文件 - `logs/` - 日志文件 - `config/` - 配置文件(只读) ## 架构支持 本版本会自动检测当前平台架构: - AMD64 (x86_64) - 适用于大多数Intel/AMD服务器 - ARM64 (aarch64) - 适用于Apple Silicon Mac、ARM服务器 ## 故障排除 如果遇到问题: 1. 检查Docker是否正常运行:`docker info` 2. 检查端口是否被占用:`netstat -tlnp | grep 505` 3. 查看容器日志:`docker-compose logs` 4. 重启服务:`docker-compose restart` EOF # 7. 显示镜像信息 echo "[信息] Docker镜像信息:" docker images "$IMAGE_NAME:latest" # 8. 压缩最终包 echo "[信息] 压缩最终部署包..." tar -czf "$ARCHIVE_NAME" "$EXPORT_DIR" # 9. 显示结果 echo "" echo "=== 创建完成 ===" echo "部署包: $ARCHIVE_NAME" echo "部署包大小: $(du -sh "$ARCHIVE_NAME" | cut -f1)" echo "构建架构: $TARGET_PLATFORM ($ARCH_NAME)" echo "Docker镜像大小: $(docker images "$IMAGE_NAME:latest" --format "{{.Size}}" 2>/dev/null || echo "约300MB")" echo "" echo "部署方法:" echo "1. 解压: tar -xzf $ARCHIVE_NAME" echo "2. 进入目录: cd $EXPORT_DIR" echo "3. 运行: ./deploy.sh" echo "" # 清理Docker镜像(可选) read -p "是否删除本地Docker镜像?(y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then docker rmi "$IMAGE_NAME:latest" echo "[信息] 已删除本地Docker镜像" fi echo "[完成] Docker Compose版本部署包创建完成(简化版)!"