3. GitLab CI基础:.gitlab-ci.yml文件结构、Runner注册与配置、Pipeline与Job概念
好,咱们进入正题。GitLab CI 说白了就是一套自动化流水线的引擎。你写好配置文件,它负责跑。我刚开始接触的时候,觉得这东西挺玄乎,后来拆开一看,核心就三个东西:配置文件、执行器(Runner)、流水线(Pipeline)。今天咱们一个一个说清楚。
3.1 .gitlab-ci.yml 文件结构
这个文件是 GitLab CI 的灵魂。你把它放在项目根目录,GitLab 就会自动识别。我习惯叫它「流水线剧本」——你写什么,它就演什么。
核心结构:
- stages:定义流水线的阶段顺序
- Job:每个任务块,属于某个 stage
- script:Job 要执行的命令
- 全局配置:如 before_script、after_script、variables
来看一个最简单的例子:
stages:
- build
- test
- deploy
build_job:
stage: build
script:
- echo "编译代码..."
- make build
test_job:
stage: test
script:
- echo "运行测试..."
- make test
deploy_job:
stage: deploy
script:
- echo "部署到服务器..."
- ./deploy.sh
嗯,这里要注意:Job 的名字可以随便起,但 stage 必须和 stages 里定义的一致。我见过有人把 stage 拼错了,结果 Job 一直不跑,排查了半天。
我的习惯:Job 命名用下划线分隔,比如 build_frontend、test_backend。这样一眼就能看出是干什么的。
3.2 Runner 注册与配置
Runner 是真正干活的机器。GitLab 本身不执行你的脚本,它把任务派发给 Runner。你可以用 GitLab 官方的共享 Runner,也可以自己搭。
我个人建议:生产环境一定要用自建 Runner。为什么?共享 Runner 的资源是有限的,排队能排到你怀疑人生。我曾经在项目高峰期,一个 Job 等了 40 分钟才轮到——从那以后,我再也没用过共享 Runner。
注册 Runner 的步骤
- 在 GitLab 项目里找到 Settings → CI/CD → Runners
- 拿到注册 token
- 在服务器上执行注册命令
# 安装 GitLab Runner(以 Ubuntu 为例)
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install gitlab-runner
# 注册 Runner
sudo gitlab-runner register
# 输入 GitLab 实例 URL
# 输入注册 token
# 输入 Runner 描述(比如 "生产环境构建机")
# 选择执行器(我一般用 docker)
# 输入默认镜像(比如 alpine:latest)
避坑指南:我曾经注册完 Runner 后发现 Job 一直处于 pending 状态。后来发现是 Runner 的 tag 没设置对。如果你在 .gitlab-ci.yml 里指定了 tags,Runner 必须包含对应的 tag 才能接活。
Runner 的三种类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| Shared Runner | 所有项目共享 | 小团队、测试项目 |
| Group Runner | 组内项目共享 | 部门级项目 |
| Specific Runner | 仅限指定项目 | 生产环境、敏感项目 |
你想想看,如果公司有多个项目,用 Group Runner 最划算。既不用每个项目都配一台机器,又能保证资源隔离。
3.3 Pipeline 与 Job 概念
Pipeline 就是一次完整的流水线执行。它由多个 Job 组成,Job 按 stage 顺序执行。说白了,Pipeline 是「面」,Job 是「点」。
关键概念:
- Pipeline:一次完整的 CI/CD 流程
- Job:Pipeline 里的一个任务单元
- Stage:Job 的逻辑分组,同 stage 的 Job 可以并行执行
- Artifact:Job 产生的文件,可以传递给后续 Job
我画了一张图,帮你理清它们的关系:
这张图你看懂了吗?Pipeline 从左到右执行,每个 Stage 里的 Job 可以并行跑。比如 build 阶段,compile 和 lint 可以同时进行。等 build 全部完成后,才进入 test 阶段。
我的经验:合理利用并行能大幅缩短流水线时间。比如前端构建和后端构建没有依赖关系,就放在同一个 stage 里并行跑。我曾经把一个 15 分钟的流水线优化到 6 分钟,就是靠这个思路。
3.4 实战:一个完整的 .gitlab-ci.yml
光说不练假把式。咱们写一个真实项目会用到的配置:
stages:
- install
- test
- build
- deploy
variables:
NODE_VERSION: "18"
APP_NAME: "my-app"
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
before_script:
- node -v
- npm -v
install_deps:
stage: install
script:
- npm ci
artifacts:
paths:
- node_modules/
expire_in: 1 hour
run_lint:
stage: test
script:
- npm run lint
needs: [install_deps]
run_unit_test:
stage: test
script:
- npm run test:unit
needs: [install_deps]
build_app:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 day
needs: [install_deps]
deploy_staging:
stage: deploy
script:
- scp -r dist/* user@staging-server:/var/www/${APP_NAME}/
only:
- develop
needs: [build_app]
deploy_production:
stage: deploy
script:
- scp -r dist/* user@prod-server:/var/www/${APP_NAME}/
only:
- main
when: manual
needs: [build_app]
注意:deploy_production 我加了 when: manual,意思是需要手动点击才能执行。生产环境部署一定要加这个,防止手滑。我曾经有一次不小心 push 到 main 分支,结果自动部署到生产了……嗯,那天晚上我加班到凌晨两点。
3.5 常见问题与避坑
- Job 一直 pending?检查 Runner 是否在线,tag 是否匹配。
- Pipeline 卡住不动?看看是不是某个 stage 的 Job 失败了,默认情况下后续 stage 不会执行。
- Artifact 太大?设置 expire_in 自动清理,不然磁盘会爆。
- Runner 跑着跑着断了?检查服务器内存和磁盘,我遇到过好几次 OOM 导致 Runner 挂掉。
好了,GitLab CI 的基础就这些。你先把 .gitlab-ci.yml 写出来,注册一个 Runner,跑通第一个 Pipeline。后面咱们再聊更高级的玩法。