DeOldify服务CI/CD流水线:GitHub Actions自动构建镜像+部署验证
1. 项目概述
DeOldify是一款基于深度学习技术的图像上色工具,能够将黑白照片自动转换为彩色照片。本文将详细介绍如何通过GitHub Actions构建完整的CI/CD流水线,实现DeOldify服务的自动化构建、测试和部署。
1.1 技术架构
- 核心模型:基于U-Net架构的DeOldify深度学习模型
- 服务框架:Flask + Gunicorn
- 容器化:Docker镜像
- CI/CD工具:GitHub Actions
- 部署平台:支持Kubernetes、ECS等主流容器平台
2. CI/CD流水线设计
2.1 整体流程
- 代码提交:开发者推送代码到GitHub仓库
- 自动触发:GitHub Actions检测到变更并启动流水线
- 构建阶段:构建Docker镜像并推送到镜像仓库
- 测试阶段:运行自动化测试验证服务功能
- 部署阶段:将镜像部署到测试环境
- 验证阶段:执行端到端测试验证部署结果
- 生产发布:人工审核后发布到生产环境
2.2 关键组件
- workflow文件:
.github/workflows/deoldify-ci-cd.yml - Dockerfile:定义容器构建规范
- 测试脚本:包含单元测试和集成测试
- 部署脚本:Kubernetes/ECS部署配置
3. 实现步骤详解
3.1 准备工作
3.1.1 项目结构
deoldify-service/ ├── app/ │ ├── main.py # Flask应用入口 │ ├── model.py # 模型加载与推理 │ └── utils.py # 工具函数 ├── tests/ │ ├── unit/ # 单元测试 │ └── integration/ # 集成测试 ├── Dockerfile # 容器构建文件 ├── requirements.txt # Python依赖 └── .github/ └── workflows/ └── deoldify-ci-cd.yml # CI/CD工作流3.1.2 Dockerfile配置
FROM python:3.9-slim WORKDIR /app # 安装系统依赖 RUN apt-get update && apt-get install -y \ libgl1-mesa-glx \ libglib2.0-0 \ && rm -rf /var/lib/apt/lists/* # 复制项目文件 COPY requirements.txt . COPY . . # 安装Python依赖 RUN pip install --no-cache-dir -r requirements.txt # 下载模型 RUN python -c "from app.model import load_model; load_model()" # 暴露端口 EXPOSE 7860 # 启动命令 CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "4", "app.main:app"]3.2 GitHub Actions配置
3.2.1 基础工作流
name: DeOldify CI/CD Pipeline on: push: branches: [ main ] pull_request: branches: [ main ] env: IMAGE_NAME: deoldify-service REGISTRY: ghcr.io REPOSITORY: ${{ github.repository }} jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.9' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install pytest - name: Run unit tests run: | pytest tests/unit -v - name: Build Docker image run: docker build -t $IMAGE_NAME . - name: Run integration tests run: | docker run -d -p 7860:7860 --name deoldify-test $IMAGE_NAME sleep 10 # 等待服务启动 pytest tests/integration -v docker stop deoldify-test docker rm deoldify-test3.2.2 镜像构建与推送
build-and-push: needs: build-and-test runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . push: true tags: | ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ github.sha }}3.2.3 部署到测试环境
deploy-to-test: needs: build-and-push runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: Deploy to ECS run: | # 更新ECS任务定义 aws ecs register-task-definition \ --family deoldify-test \ --network-mode awsvpc \ --execution-role-arn ${{ secrets.ECS_TASK_ROLE }} \ --container-definitions '[ { "name": "deoldify", "image": "${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ github.sha }}", "essential": true, "portMappings": [ { "containerPort": 7860, "hostPort": 7860 } ], "environment": [ { "name": "ENVIRONMENT", "value": "test" } ] } ]' # 更新服务 aws ecs update-service \ --cluster deoldify-cluster \ --service deoldify-test \ --task-definition deoldify-test \ --force-new-deployment3.3 测试验证
3.3.1 单元测试示例
# tests/unit/test_model.py import pytest from app.model import colorize_image from PIL import Image import numpy as np def test_colorize_image(): # 创建测试用的黑白图像 test_img = Image.new('L', (100, 100), color=128) # 调用上色函数 colored_img = colorize_image(test_img) # 验证结果 assert colored_img.mode == 'RGB' assert colored_img.size == (100, 100) assert np.array(colored_img).shape == (100, 100, 3)3.3.2 集成测试示例
# tests/integration/test_api.py import requests import base64 from io import BytesIO from PIL import Image BASE_URL = "http://localhost:7860" def test_health_check(): response = requests.get(f"{BASE_URL}/health") assert response.status_code == 200 assert response.json()["status"] == "healthy" def test_colorize_api(): # 创建测试图像 test_img = Image.new('L', (100, 100), color=128) img_byte_arr = BytesIO() test_img.save(img_byte_arr, format='JPEG') img_byte_arr.seek(0) # 调用API files = {'image': ('test.jpg', img_byte_arr, 'image/jpeg')} response = requests.post(f"{BASE_URL}/colorize", files=files) # 验证响应 assert response.status_code == 200 result = response.json() assert result["success"] is True assert "output_img_base64" in result # 验证图像 img_data = base64.b64decode(result["output_img_base64"]) img = Image.open(BytesIO(img_data)) assert img.mode == 'RGB' assert img.size == (100, 100)4. 高级配置与优化
4.1 多阶段构建优化
# 构建阶段 FROM python:3.9-slim as builder WORKDIR /app COPY requirements.txt . RUN apt-get update && apt-get install -y gcc python3-dev RUN pip install --user -r requirements.txt # 运行时阶段 FROM python:3.9-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH ENV PYTHONPATH=/app # 其余配置与之前相同...4.2 缓存优化
# 在GitHub Actions中添加缓存步骤 - name: Cache Python dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} restore-keys: | ${{ runner.os }}-pip-4.3 安全扫描
- name: Scan for vulnerabilities uses: aquasecurity/trivy-action@master with: image-ref: ${{ env.IMAGE_NAME }} format: 'table' exit-code: '1' ignore-unfixed: true severity: 'CRITICAL,HIGH'5. 部署验证
5.1 自动化验证脚本
#!/bin/bash # 验证服务健康状态 health_check() { local retries=5 local delay=5 for ((i=1; i<=retries; i++)); do response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:7860/health) if [ "$response" -eq 200 ]; then echo "Service is healthy" return 0 fi echo "Attempt $i: Service not ready, waiting $delay seconds..." sleep $delay done echo "Health check failed after $retries attempts" return 1 } # 验证图像上色功能 test_colorize() { local test_image="test.jpg" local output_file="output.jpg" # 创建测试图像 convert -size 100x100 xc:gray -quality 90 "$test_image" # 调用API response=$(curl -s -X POST -F "image=@$test_image" http://localhost:7860/colorize) # 检查响应 if echo "$response" | jq -e '.success == true' >/dev/null; then echo "Colorize API responded successfully" # 保存结果图像 echo "$response" | jq -r '.output_img_base64' | base64 -d > "$output_file" if [ -s "$output_file" ]; then echo "Colorized image saved to $output_file" return 0 else echo "Failed to save colorized image" return 1 fi else echo "Colorize API failed: $response" return 1 fi } # 主验证流程 main() { if health_check; then if test_colorize; then echo "Deployment validation PASSED" exit 0 fi fi echo "Deployment validation FAILED" exit 1 } main5.2 监控与告警
- name: Setup monitoring run: | # 安装Prometheus exporter pip install prometheus-flask-exporter # 修改应用代码添加监控端点 echo "from prometheus_flask_exporter import PrometheusMetrics" >> app/main.py echo "metrics = PrometheusMetrics(app)" >> app/main.py6. 总结
通过本文介绍的CI/CD流水线,我们实现了DeOldify服务的自动化构建、测试和部署流程。这套方案具有以下优势:
- 自动化程度高:从代码提交到部署验证全流程自动化
- 质量保障:包含多层次的测试验证
- 可扩展性强:易于扩展到其他深度学习服务
- 安全可靠:包含安全扫描和健康检查
- 高效部署:支持快速迭代和回滚
实际部署时,可以根据具体需求调整各阶段配置,如增加性能测试、蓝绿部署等高级特性,进一步提升交付质量和效率。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。