返回文章列表
技术2026-05-10

从零搭建 CI/CD 流水线

使用 GitHub Actions 从零搭建完整的 CI/CD 流水线,包含 Docker 构建、自动化测试、部署和环境管理。

为什么需要 CI/CD

如果你还在手动执行以下操作——运行测试、构建 Docker 镜像、SSH 到服务器拉代码、重启服务——那么你的部署流程存在巨大的效率损失和人为失误风险。CI/CD(持续集成/持续部署)的目标就是将这些重复性操作自动化,让每次代码推送都能自动触发一系列检查和部署。

GitHub Actions 工作流基础

GitHub Actions 是目前最流行的 CI/CD 平台之一,与 GitHub 仓库深度集成,配置简单。一个工作流文件由三个核心概念组成:

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

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm test

Docker 构建与推送

将应用容器化后,CI 流水线需要构建 Docker 镜像并推送到镜像仓库:

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: |
            myapp:latest
            myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

这里用到两个关键技巧:GitHub Actions Cache 用于缓存 Docker 层,commit SHA 作为 tag 用于追溯每个镜像对应的代码版本。

自动化测试矩阵

一个成熟的项目通常需要在多个 Node.js 版本、多个操作系统上运行测试。GitHub Actions 的 matrix 策略可以轻松实现:

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

这个配置会生成 3x2 = 6 个并行运行的测试 Job,确保你的代码在目标环境中都能正常工作。

部署到 VPS / 云服务器

构建完成后,下一步是把新镜像部署到服务器。使用 SSH 方式部署是最常见的方案:

jobs:
  deploy:
    needs: [test, build-and-push]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d --remove-orphans
            docker image prune -f
安全提示:永远不要在代码中硬编码服务器地址、用户名或密码。使用 GitHub Secrets 管理所有敏感信息。

环境密钥与机密管理

CI/CD 流水线中需要管理多种机密信息:

# 使用 OIDC 认证 AWS(无需存储 AWS 密钥)
jobs:
  deploy:
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789:role/github-actions
          aws-region: us-east-1

PR 预览部署

为每个 Pull Request 自动创建预览环境,让 Code Review 变得更直观:

# 使用 Vercel 的预览部署(自动生成独立 URL)
jobs:
  preview:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          github-comment: true

通知集成

部署完成后,应该通知团队成员。常用的通知方式包括 Slack 和钉钉:

# Slack 通知
- name: Notify Slack
  uses: slackapi/slack-github-action@v1
  with:
    payload: |
      {
        "text": "部署成功: ${{ github.repository }} @ ${{ github.sha }}"
      }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

总结

一套完整的 CI/CD 流水线应该覆盖:代码推送 -> 自动测试 -> 构建镜像 -> 部署到服务器 -> 通知团队。从最简单的 lint + test 开始,逐步添加 Docker 构建和自动部署。记住:CI/CD 的价值在于"早发现问题、早修复问题",而不是追求配置的复杂度。


返回文章列表
标签:CI/CDGitHub ActionsDevOps