为什么需要 CI/CD
如果你还在手动执行以下操作——运行测试、构建 Docker 镜像、SSH 到服务器拉代码、重启服务——那么你的部署流程存在巨大的效率损失和人为失误风险。CI/CD(持续集成/持续部署)的目标就是将这些重复性操作自动化,让每次代码推送都能自动触发一系列检查和部署。
GitHub Actions 工作流基础
GitHub Actions 是目前最流行的 CI/CD 平台之一,与 GitHub 仓库深度集成,配置简单。一个工作流文件由三个核心概念组成:
- Workflow:一个
.github/workflows/*.yml文件,定义整个自动化流程 - Job:工作流中的一个执行单元。默认并行运行,可以设置依赖关系
- Step:Job 中的单个步骤,可以是运行命令或使用社区 Action
# .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 流水线中需要管理多种机密信息:
- Repository Secrets:仓库级别的密钥,如 Docker Hub 密码、SSH 私钥
- Environment Secrets:环境级别的密钥,如 staging 和 production 使用不同的 API 密钥
- OIDC(OpenID Connect):不用存储长期密钥,通过短期令牌认证云服务提供商
# 使用 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 的价值在于"早发现问题、早修复问题",而不是追求配置的复杂度。