📦 第07章 · CI/CD 与 Runner

.gitlab-ci.yml 简介

CI/CD 与 Runner

这一章讲 GitLab 内置的持续集成/交付(CI/CD):往仓库放一个 .gitlab-ci.yml,GitLab 就能在每次提交/合并时自动跑测试、构建、部署。这是把"手动上线"变成"一点就发布"的核心。

CI/CD 是什么

  • CI(持续集成):每次 push 自动编译 + 跑测试,尽早发现坏代码。
  • CD(持续交付/部署):测试过了自动发布到测试/生产环境。

在 GitLab 里,这一切由 Runner(执行任务的 worker)跑 jobs。Runner 可以注册成共享或专用。

核心三件套:Runner / Pipeline / Job

概念 说明
Runner 跑 CI 任务的机器(可本机/容器/云)
Pipeline 一次提交触发的一整套流程
Job 流程里最小执行单元(如 build、test、deploy)
Stage 一组可以被并行/顺序执行的 job(如 build → test → deploy)

安装并注册 Runner(本机复用即可)

# 装 gitlab-runner
curl -fsSL https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner

# 注册(需要 GitLab 设置的 registration token)
sudo gitlab-runner register
# 按提示填:
#   GitLab 地址: https://gitlab.bangdream.xyz/
#   registration token: 从 Settings→CI/CD→Runners 拿
#   描述 / 标签(如 shell,docker)

提示 | 简单场景选 executor: shell(直接在宿主机/容器 shell 里跑)。要隔离环境用 docker executor。

.gitlab-ci.yml 怎么写

在仓库根目录放 .gitlab-ci.yml,定义 stages 和 jobs:

stages:
  - build
  - test
  - deploy

variables:
  NODE_VERSION: "24"

build:
  stage: build
  image: node:24
  script:
    - npm ci
    - npm run build
  artifacts:
    paths: [dist/]        # 保留构建产物

test:
  stage: test
  image: node:24
  script:
    - npm run test

deploy:
  stage: deploy
  only:
    - main                # 只在 main 分支部署
  script:
    - ssh user@server "cd /var/www/myapp && git pull && systemctl restart myapp"

常用关键字

关键字 作用
stages 定义阶段顺序
image 用哪个 Docker 镜像跑(docker executor)
script 该 job 要执行的命令序列
artifacts 保留可下载的产物给下个 job/页面
only/except 限定哪些分支/事件触发
when: manual 手动点击触发(适合生产发布)
needs 提前执行依赖的 job(不必等同 stage)
cache 缓存依赖加速
rules 更灵活的触发条件(推荐替代 only/except)

一个"手动发布生产"的示例

deploy_prod:
  stage: deploy
  only:
    - main
  when: manual              # 测试通过后,人工点击才发布
  script:
    - echo "Deploy to production"
    - ssh ops@server "cd /var/www/app && git reset --hard origin/main && npm install --production && systemctl restart app"
  environment:
    name: production
    url: https://app.example.com

常见坑与排查

坑 现象 解决
Pipeline 一直 pending 没注册 Runner / Runner 离线 sudo gitlab-runner list、gitlab-ctl status | grep runner
找不到命令 executor shell 或镜像缺工具 换 image 或 apt install/npm i -g
仓库拉取失败 SSH key/凭据没配 用 CI before_script 配好 pull key;走 CI_JOB_TOKEN 拉私有仓库
构建慢 无缓存/资源小 加 cache: key;考虑 Runner 资源
发布重复 每次 push 都部署 用 only: main + when: manual 收紧

注意 | deploy 里如果在 runner 上执行服务器的部署动作,注意 ssh 到目标机时的权限与免密配置(用 ssh-keygen + ssh-copy-id)。不要把明文密码写进仓库。

让 CI 驱动"一条流水线":构建 → 测试 → 发布

实际项目里可这样组织:

push 提交 → build(job) → test(job) → (main 分支) deploy(job, 可能手动)
              │ 构建产物           │ 单元/集成测试

相关命令

  • sudo gitlab-runner register / list / run
  • sudo gitlab-ctl status 看 GitLab 组件
  • Web:项目 → CI/CD → Pipelines 看流水线;Settings → CI/CD → Runners 注册 Runner
  • 日志:sudo gitlab-runner run(前台调试)、Web 里 job 详情看 console 输出