高级3-4 小时·DevOps

Docker 化的 CI/CD 流水线

使用 GitHub Actions + Docker 构建一个完整的自动化测试、构建、部署流水线

Dockerci-cdgithub-actionsautomationdeployment

Docker 化的 CI/CD 流水线

使用 GitHub Actions + Docker 构建一个完整的自动化测试、构建、部署流水线

你将学到

  • 使用 GitHub Actions 定义 CI/CD 流水线
  • 自动化构建和推送 Docker 镜像
  • 实现自动化测试和部署
  • 管理环境变量和密钥

前置知识

架构设计

代码推送 → GitHub Actions → 构建镜像 → 推送仓库 → 部署服务器
   │            │              │           │           │
   └────────────┴──────────────┴───────────┴───────────┘
                    自动化流水线

实现步骤

第一步:项目结构

myapp/
├── .github/
│   └── workflows/
│       └── ci.yml
├── Dockerfile
├── docker-compose.yml
├── app/
└── tests/

第二步:Dockerfile(多阶段)

# Dockerfile
# 测试阶段
FROM python:3.11-slim AS test

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN pytest tests/ -v

# 构建阶段
FROM python:3.11-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# 生产阶段
FROM python:3.11-slim AS production

RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app

COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser . .

USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH

EXPOSE 8000
HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1
CMD ["python", "app.py"]

第三步:GitHub Actions 配置

# .github/workflows/ci.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: |
          docker build --target test -t myapp:test .
          docker run --rm myapp:test

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'

    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=sha
            type=raw,value=latest

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'

    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d

第四步:Docker Compose(部署用)

# docker-compose.yml
version: "3.8"

services:
  app:
    image: ghcr.io/username/myapp:latest
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=${REDIS_URL}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 3s
      retries: 3

第五步:环境变量和密钥管理

# GitHub Secrets 配置
# Settings → Secrets and variables → Actions

# 必需的密钥:
# - SERVER_HOST: 服务器地址
# - SERVER_USER: 服务器用户名
# - SERVER_KEY: SSH 私钥
# - DATABASE_URL: 数据库连接字符串
# - REDIS_URL: Redis 连接字符串

完整项目结构

myapp/
├── .github/
│   └── workflows/
│       └── ci.yml          # CI/CD 流水线定义
├── Dockerfile              # 多阶段构建
├── docker-compose.yml      # 部署配置
├── app/
│   └── app.py              # 应用代码
├── tests/
│   └── test_app.py         # 测试代码
└── requirements.txt

最佳实践

  1. 多阶段构建:测试、构建、生产分离
  2. 自动化测试:每次提交都运行测试
  3. 镜像标签:使用 Git SHA 作为镜像标签
  4. 密钥管理:使用 GitHub Secrets 存储敏感信息
  5. 健康检查:确保部署后服务可用

常见问题

Q: 如何回滚部署? A: 使用之前的镜像标签重新部署。

Q: 如何查看部署日志? A: 在 GitHub Actions 页面查看工作流日志。

Q: 如何支持多环境部署? A: 使用 GitHub Environments 管理不同环境。

扩展挑战

  1. 添加 Slack/钉钉通知
  2. 实现蓝绿部署
  3. 添加自动回滚机制

相关课程

课程相关章节
DockerCI/CD 与 Docker
Docker多阶段构建
Docker镜像仓库
DockerDocker Compose