Docker: CI/CD集成

最后更新:2026-08-26

代码 push → 自动测试 → 自动构建镜像 → 自动部署——CI/CD 让发布从手动操作变成自动化流水线。

1. 你将学到


2. 一个开发者的真实故事

(1) 痛点:每次部署手动 SSH 操作

Alice 每次部署都要手动 SSH 上服务器、拉代码、构建镜像、重启容器。流程是:ssh server → git pull → docker build → docker stop → docker run。一次部署 15 分钟,一周 3-4 次发布,总计 1 小时/周浪费在重复操作上。更糟的是有一次半夜发布时手误敲错了命令。

(2) GitHub Actions CI/CD 的解法

Bob 用 GitHub Actions 写了一个工作流:代码 push → 自动测试 → build 镜像 → push 到仓库 → SSH deploy。

YAML
# .github/workflows/deploy.yml
name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: myorg/myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

(3) 收益:1 小时/周→0 分钟

部署完全自动化,Alice 只需 push 代码,5 分钟后自动上线。手动操作时间从 1 小时/周降到 0,且零人为错误。


3. GitHub Actions 工作流结构

(1) 工作流 YAML 结构

100%
graph LR
    PUSH["git push"] --> TRIGGER["on: push"]
    TRIGGER --> JOB1["Job: test"]
    JOB1 --> JOB2["Job: build"]
    JOB2 --> JOB3["Job: deploy"]
字段 作用 示例
name 工作流名称 Build and Deploy
on 触发条件 push, pull_request
jobs 任务定义 build, test, deploy
runs-on 运行环境 ubuntu-latest
steps 执行步骤 checkout, build, push

(1) CI/CD 三种策略对比

平台 特点 适用场景
GitHub Actions GitHub 原生集成,免费 2000 分钟/月 开源项目 + GitHub 托管
GitLab CI GitLab 原生,自建 Runner 企业内部 GitLab
Jenkins 老牌 CI/CD,插件丰富 传统企业 + 复杂流水线

4. Docker buildx 跨平台构建

▶ 示例:buildx 多架构构建(难度⭐⭐⭐)

BASH
# Create buildx builder instance
docker buildx create --name multiarch --use

# Build for amd64 + arm64 simultaneously
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myorg/myapp:latest \
  --push .

# Inspect built platforms
docker buildx imagetools inspect myorg/myapp:latest

(1) buildx vs 普通 build

维度 docker build docker buildx
多架构 ❌ 只能构建当前架构 ✅ 同时构建多架构
缓存导出 ❌ 本地缓存 ✅ gha/registry/s3
输出格式 本地镜像 镜像/OCI/tar/registry
并行构建

5. CI 缓存策略

(1) 缓存类型对比

类型 语法 位置 适用场景
gha cache-from: type=gha GitHub Actions Cache GitHub Actions CI
registry cache-from: type=registry Docker Registry 任何 CI 平台
local cache-from: type=local 本地文件系统 自建 Runner

▶ 示例:CI 缓存配置(难度⭐⭐⭐)

YAML
# GitHub Actions with build cache
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: myorg/myapp:${{ github.sha }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

▶ 示例:自动标签策略(难度⭐⭐)

YAML
# Docker metadata action for automatic tagging
- uses: docker/metadata-action@v5
  id: meta
  with:
    images: myorg/myapp
    tags: |
      type=sha,prefix=
      type=ref,event=branch
      type=semver,pattern={{version}}
      type=raw,value=latest,enable={{is_default_branch}}

6. SSH 部署步骤

▶ 示例:SSH 部署到服务器(难度⭐⭐⭐)

YAML
# Deploy step in GitHub Actions
- name: Deploy to server
  uses: appleboy/ssh-action@v1
  with:
    host: ${{ secrets.SERVER_HOST }}
    username: ${{ secrets.SERVER_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /opt/myapp
      docker compose pull
      docker compose up -d --remove-orphans
      docker image prune -f
🔒 安全: 服务器地址、SSH 密钥等敏感信息用 GitHub Secrets 存储,不要写在 YAML 中。Settings → Secrets and variables → Actions 中添加。**


7. 完整示例:Node.js 应用 CI/CD

YAML
# ============================================
# .github/workflows/deploy.yml
# Full CI/CD: test → build → push → deploy
# ============================================

name: CI/CD Pipeline

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

env:
  REGISTRY: docker.io
  IMAGE_NAME: myorg/myapp

jobs:
  # ---------- Job 1: Test ----------
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: |
          docker build --target builder -t test-image .
          docker run test-image npm test

  # ---------- Job 2: Build & Push ----------
  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

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

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  # ---------- Job 3: Deploy ----------
  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d --remove-orphans
            docker image prune -f
            echo "Deployed at $(date)"

❓ 常见问题

Q buildx 和普通 build 有什么区别?
A buildx 是 Docker BuildKit 的 CLI 扩展。主要优势:① 多架构同时构建(amd64+arm64);② 高级缓存导出(gha/registry);③ 并行构建。GitHub Actions 中建议始终用 buildx。
Q CI 中如何共享 Docker layer 缓存?
Acache-from: type=gha(GitHub Actions)或 type=registry(通用)。gha 缓存存储在 GitHub Actions Cache 中,同一仓库的 workflow 自动共享。registry 缓存存在 Registry 的特殊 manifest 中,任何 CI 平台可用。
Q 多架构镜像怎么构建?
A docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .。需要 QEMU 模拟器(docker/setup-qemu-action)+ buildx builder。构建产物是一个 manifest list,docker pull 时自动选择当前架构的镜像。
Q CI/CD 中的敏感信息怎么管理?
A GitHub Secrets(Settings → Secrets)。SSH 密钥、数据库密码、Registry 凭据都存在 Secrets 中,YAML 中用 ${{ secrets.XXX }} 引用。Secrets 加密存储,日志中自动遮蔽。
Q 部署失败怎么自动回滚?
A 两种方式:① 部署脚本中加健康检查,失败时 docker compose rollback(Swarm)或手动切回旧版本;② 镜像保留最近 N 个版本 tag,回滚只需 docker compose up -d myapp:previous-sha。自动回滚在 Swarm/K8s 中内置支持。

📖 小节


📝 作业

  1. 基础题(难度⭐):为第 12 课的 Flask 应用编写 GitHub Actions 构建工作流,push 到 main 分支时自动 build + push 镜像。
  2. 进阶题(难度⭐⭐):用 buildx 构建 amd64+arm64 双架构镜像,推送到 Docker Hub。
  3. 挑战题(难度⭐⭐⭐):配置完整的 CI/CD(test → build → SSH deploy),用 GitHub Secrets 管理服务器密钥,验证 push 后自动部署。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏