509 lines
14 KiB
Bash
Executable File
509 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# DMS合规性测试工具 - FastAPI版本 Docker Compose部署包创建脚本
|
||
# 使用Alpine Linux + 多阶段构建 + Docker Compose管理
|
||
# 自动检测当前平台架构,使用5051端口
|
||
|
||
set -e
|
||
|
||
# 配置变量
|
||
EXPORT_DIR="dms-compliance-fastapi-$(date +%Y%m%d-%H%M%S)"
|
||
IMAGE_NAME="compliance-dms-fastapi"
|
||
ARCHIVE_NAME="$EXPORT_DIR.tar.gz"
|
||
|
||
echo "=== DMS合规性测试工具 FastAPI版本 Docker Compose部署包创建脚本 ==="
|
||
echo "[信息] 使用FastAPI框架,自动生成API文档"
|
||
echo "[信息] 服务端口: 5051 (与历史查看器端口一致)"
|
||
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 "[信息] 复制必要文件(FastAPI版本)..."
|
||
mkdir -p "$TEMP_BUILD_DIR"/{ddms_compliance_suite,custom_stages,custom_testcases,templates,static,assets}
|
||
|
||
# 复制FastAPI相关文件
|
||
echo "[信息] 复制FastAPI核心文件..."
|
||
for file in fastapi_server.py requirements_fastapi.txt; 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) 个文件"
|
||
|
||
# 创建FastAPI专用Dockerfile
|
||
echo "[信息] 创建FastAPI专用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_fastapi.txt .
|
||
|
||
# 升级pip并安装依赖
|
||
RUN pip install --upgrade pip setuptools wheel && \
|
||
pip install --no-cache-dir --user -r requirements_fastapi.txt
|
||
|
||
# 第二阶段:运行时镜像
|
||
FROM python:3.9-alpine
|
||
|
||
# 安装运行时依赖
|
||
RUN apk update && \
|
||
apk add --no-cache \
|
||
curl \
|
||
bash && \
|
||
rm -rf /var/cache/apk/*
|
||
|
||
# 从构建阶段复制Python包
|
||
COPY --from=builder /root/.local /root/.local
|
||
|
||
# 设置工作目录
|
||
WORKDIR /app
|
||
|
||
# 复制应用代码
|
||
COPY . .
|
||
|
||
# 创建必要目录
|
||
RUN mkdir -p /app/logs /app/test_reports /app/uploads
|
||
|
||
# 设置环境变量
|
||
ENV PATH=/root/.local/bin:$PATH
|
||
ENV PYTHONPATH=/app
|
||
ENV PYTHONUNBUFFERED=1
|
||
|
||
# 暴露端口(使用5051端口)
|
||
EXPOSE 5051
|
||
|
||
# 健康检查
|
||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||
CMD curl -f http://localhost:5051/ || exit 1
|
||
|
||
# 启动FastAPI服务器
|
||
CMD ["python3", "fastapi_server.py", "--host", "0.0.0.0", "--port", "5051"]
|
||
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 \
|
||
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_fastapi.txt
|
||
|
||
# 创建必要目录
|
||
RUN mkdir -p /app/logs /app/test_reports /app/uploads
|
||
|
||
# 设置环境变量
|
||
ENV PYTHONPATH=/app
|
||
ENV PYTHONUNBUFFERED=1
|
||
|
||
# 暴露端口
|
||
EXPOSE 5051
|
||
|
||
# 健康检查
|
||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||
CMD curl -f http://localhost:5051/ || exit 1
|
||
|
||
# 启动FastAPI服务器
|
||
CMD ["python3", "fastapi_server.py", "--host", "0.0.0.0", "--port", "5051"]
|
||
EOF
|
||
|
||
# 显示构建目录大小
|
||
echo "[信息] 临时构建目录大小: $(du -sh "$TEMP_BUILD_DIR" | cut -f1)"
|
||
|
||
# 2. 构建Docker镜像
|
||
echo "[信息] 构建FastAPI 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-fastapi:
|
||
image: compliance-dms-fastapi:latest
|
||
container_name: dms-compliance-fastapi
|
||
ports:
|
||
- "5051:5051" # FastAPI服务器端口
|
||
volumes:
|
||
# 持久化测试报告
|
||
- ./test_reports:/app/test_reports
|
||
# 持久化上传文件
|
||
- ./uploads:/app/uploads
|
||
# 持久化日志
|
||
- ./logs:/app/logs
|
||
# 如果需要自定义配置文件
|
||
- ./config:/app/config:ro
|
||
environment:
|
||
- PYTHONUNBUFFERED=1
|
||
- TZ=Asia/Shanghai
|
||
- HOST=0.0.0.0
|
||
- PORT=5051
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:5051/"]
|
||
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合规性测试工具 - FastAPI版本 Docker Compose部署脚本
|
||
|
||
set -e
|
||
|
||
echo "=== DMS合规性测试工具 FastAPI版本部署 ==="
|
||
|
||
# 检查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 "[信息] 启动FastAPI服务..."
|
||
if command -v docker-compose >/dev/null 2>&1; then
|
||
docker-compose up -d
|
||
else
|
||
docker compose up -d
|
||
fi
|
||
|
||
echo "[成功] FastAPI版本部署完成!"
|
||
echo ""
|
||
echo "访问地址:"
|
||
echo "- 主服务: http://localhost:5051"
|
||
echo "- API文档 (Swagger UI): http://localhost:5051/docs"
|
||
echo "- API文档 (ReDoc): http://localhost:5051/redoc"
|
||
echo "- 健康检查: http://localhost:5051/"
|
||
echo "- 服务信息: http://localhost:5051/info"
|
||
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"
|
||
echo ""
|
||
echo "FastAPI特性:"
|
||
echo "- 自动生成的交互式API文档"
|
||
echo "- 强类型数据验证"
|
||
echo "- 高性能异步处理"
|
||
echo "- 支持分页参数 (page_size, page_no)"
|
||
EOF
|
||
|
||
chmod +x "$EXPORT_DIR/deploy.sh"
|
||
|
||
# 6. 创建README
|
||
echo "[信息] 创建README..."
|
||
cat > "$EXPORT_DIR/README.md" << 'EOF'
|
||
# DMS合规性测试工具 - FastAPI版本
|
||
|
||
## 特点
|
||
- 基于FastAPI框架,提供自动生成的交互式API文档
|
||
- 基于Alpine Linux,镜像体积极小(约350MB)
|
||
- 多阶段构建,优化层结构
|
||
- 使用5051端口,与历史查看器端口一致
|
||
- 支持数据持久化和健康检查
|
||
- 自动检测当前平台架构,无需手动选择
|
||
- 强类型数据验证和详细的API文档
|
||
|
||
## 部署方法
|
||
|
||
1. 解压部署包
|
||
2. 运行部署脚本:
|
||
```bash
|
||
./deploy.sh
|
||
```
|
||
3. 访问服务:
|
||
- 主服务: http://localhost:5051
|
||
- API文档 (Swagger UI): http://localhost:5051/docs
|
||
- API文档 (ReDoc): http://localhost:5051/redoc
|
||
|
||
## FastAPI版本优势
|
||
|
||
### 自动API文档
|
||
- **Swagger UI**: 交互式API测试界面
|
||
- **ReDoc**: 美观的API文档展示
|
||
- **自动生成**: 基于代码自动生成,始终保持最新
|
||
|
||
### 强类型验证
|
||
- **Pydantic模型**: 自动数据验证和序列化
|
||
- **类型提示**: 完整的类型提示支持
|
||
- **错误处理**: 详细的验证错误信息
|
||
|
||
### 高性能
|
||
- **异步处理**: 基于Starlette的异步框架
|
||
- **并发支持**: 天然支持高并发请求
|
||
- **优化性能**: 比传统Flask更高的性能
|
||
|
||
## 新增功能
|
||
|
||
### 分页支持增强
|
||
- `page_size`: 分页大小(1-10000,默认1000)
|
||
- `page_no`: 起始页码(从1开始,默认1)
|
||
- 支持断点续传和跳过前面的页面
|
||
|
||
### API端点
|
||
- `GET /`: 健康检查
|
||
- `GET /info`: 服务信息
|
||
- `POST /run`: 执行测试
|
||
- `GET /reports`: 列出报告
|
||
- `GET /reports/{id}`: 下载报告
|
||
|
||
## 使用示例
|
||
|
||
### 基本测试
|
||
```bash
|
||
curl -X POST http://localhost:5051/run \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"dms": "./assets/doc/dms/domain.json",
|
||
"base_url": "https://api.example.com",
|
||
"page_size": 500,
|
||
"page_no": 1,
|
||
"strictness_level": "CRITICAL"
|
||
}'
|
||
```
|
||
|
||
### 分页测试(从第3页开始)
|
||
```bash
|
||
curl -X POST http://localhost:5051/run \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"dms": "./assets/doc/dms/domain.json",
|
||
"base_url": "https://api.example.com",
|
||
"page_size": 100,
|
||
"page_no": 3,
|
||
"ignore_ssl": true
|
||
}'
|
||
```
|
||
|
||
## 管理命令
|
||
|
||
- 查看服务状态:`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 5051`
|
||
3. 查看容器日志:`docker-compose logs`
|
||
4. 重启服务:`docker-compose restart`
|
||
5. 访问健康检查:`curl http://localhost:5051/`
|
||
|
||
## 与Flask版本对比
|
||
|
||
| 特性 | Flask版本 | FastAPI版本 |
|
||
|------|-----------|-------------|
|
||
| 端口 | 5050 | 5051 |
|
||
| API文档 | 无 | 自动生成 |
|
||
| 数据验证 | 手动 | 自动 |
|
||
| 性能 | 中等 | 高 |
|
||
| 交互测试 | 无 | 内置 |
|
||
| 类型提示 | 部分 | 完整 |
|
||
EOF
|
||
|
||
# 7. 显示镜像信息
|
||
echo "[信息] Docker镜像信息:"
|
||
docker images "$IMAGE_NAME:latest"
|
||
|
||
# 8. 压缩最终包
|
||
echo "[信息] 压缩最终部署包..."
|
||
tar -czf "$ARCHIVE_NAME" "$EXPORT_DIR"
|
||
|
||
# 9. 显示结果
|
||
echo ""
|
||
echo "=== FastAPI版本创建完成 ==="
|
||
echo "部署包: $ARCHIVE_NAME"
|
||
echo "部署包大小: $(du -sh "$ARCHIVE_NAME" | cut -f1)"
|
||
echo "构建架构: $TARGET_PLATFORM ($ARCH_NAME)"
|
||
echo "服务端口: 5051"
|
||
echo "Docker镜像大小: $(docker images "$IMAGE_NAME:latest" --format "{{.Size}}" 2>/dev/null || echo "约350MB")"
|
||
|
||
echo ""
|
||
echo "部署方法:"
|
||
echo "1. 解压: tar -xzf $ARCHIVE_NAME"
|
||
echo "2. 进入目录: cd $EXPORT_DIR"
|
||
echo "3. 运行: ./deploy.sh"
|
||
echo ""
|
||
echo "访问地址:"
|
||
echo "- 主服务: http://localhost:5051"
|
||
echo "- API文档: http://localhost:5051/docs"
|
||
echo "- ReDoc: http://localhost:5051/redoc"
|
||
echo ""
|
||
|
||
# 清理Docker镜像(可选)
|
||
read -p "是否删除本地Docker镜像?(y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
docker rmi "$IMAGE_NAME:latest"
|
||
echo "[信息] 已删除本地Docker镜像"
|
||
fi
|
||
|
||
echo "[完成] FastAPI版本 Docker Compose部署包创建完成!"
|