GitLab CI/CD 配置详细教程

1 什么是 GitLab CI/CD

GitLab CI/CD 是 GitLab 内置的持续集成、持续交付和持续部署工具。通过 `.gitlab-ci.yml` 配置文件,您可以自动化构建、测试和部署流程,显著提高开发效率和代码质量。

2 前置条件

• 注册 GitLab 账号并创建项目

• 项目仓库中包含 `.gitlab-ci.yml` 文件

• 拥有 GitLab Runner(可使用共享Runner或自建Runner)

3 基本配置结构

• 项目根目录创建 `.gitlab-ci.yml` 文件

• 配置文件使用 YAML 语法

• 基本结构示例:

stages:
  - build
  - test
  - deploy

variables:
  NODE_VERSION: "16.14.0"

build_job:
  stage: build
  script:
    - echo "构建应用..."
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

test_job:
  stage: test
  script:
    - echo "运行测试..."
    - npm run test
  coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

deploy_staging:
  stage: deploy
  environment: staging
  script:
    - echo "部署到测试环境..."
    - rsync -av --delete dist/ user@staging-server:/var/www/app/
  only:
    - main

4 核心组件详解

4.1 1. 阶段(Stages)

• 定义作业执行顺序

• 默认阶段:build, test, deploy

• 自定义阶段示例:

stages:
  - prepare
  - validate
  - build
  - test
  - security_scan
  - deploy_prod

4.2 2. 作业(Jobs)

• 最小执行单元

• 必须指定 `script` 或使用 `template`

• 作业配置示例:

build_image:
  stage: prepare
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

4.3 3. 变量(Variables)

• 全局变量和作业级变量

• 预定义变量使用:

• `$CI_COMMIT_REF_NAME`:分支/标签名

• `$CI_REGISTRY`:容器仓库地址

• `$CI_PROJECT_DIR`:项目绝对路径

• 自定义变量示例:

variables:
  DOCKER_HOST: tcp://docker:2376
  DOCKER_DRIVER: overlay2
  APP_VERSION: $CI_COMMIT_SHORT_SHA

deploy_prod:
  variables:
    DEPLOY_ENV: production
    SSH_KEY: $PROD_SSH_KEY
  script:
    - echo "部署环境: $DEPLOY_ENV"
    - echo "应用版本: $APP_VERSION"

4.4 4. 依赖与缓存(Artifacts & Cache)

• artifacts:作业间传递文件

• cache:持久化缓存(依赖包等)

cache:
  paths:
    - node_modules/
    - .npm/

build:
  script:
    - npm ci --cache .npm --prefer-offline
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/

test:
  dependencies:
    - build
  script:
    - npm test
  artifacts:
    paths:
      - test-results.xml
    expire_in: 1 week

5 高级配置技巧

5.1 1. 环境管理(Environments)

deploy_prod:
  stage: deploy
  environment:
    name: production
    url: https://prod.example.com
    auto_stop_in: 1 day
  script:
    - deploy-script.sh
  when: manual

5.2 2. 条件执行(Rules)

.job_rules:
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_TAG'
    - when: manual

build:
  extends: .job_rules
  script:
    - echo "条件构建..."

deploy:
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $DEPLOY_READY'
      when: manual
      allow_failure: true

5.3 3. 动态环境(Dynamic Environments)

deploy_review:
  stage: deploy
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_ENVIRONMENT_SLUG.example.com
    on_stop: stop_review
  script:
    - echo "部署到动态环境 $CI_ENVIRONMENT_NAME"

stop_review:
  stage: deploy
  variables:
    GIT_STRATEGY: none
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop
  when: manual
  script:
    - echo "停止环境 $CI_ENVIRONMENT_NAME"

6 实战示例:Node.js 项目完整流水线

image: node:16

stages:
  - install
  - test
  - build
  - deploy
  - cleanup

variables:
  NODE_ENV: production
  APP_DIR: /opt/myapp

cache:
  key: $CI_COMMIT_REF_SLUG
  paths:
    - node_modules/
    - .cache/npm/

install_dependencies:
  stage: install
  script:
    - npm ci --cache .npm --prefer-offline
  cache:
    paths:
      - node_modules/

run_tests:
  stage: test
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
  script:
    - npm run test:coverage
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

build_application:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 day

deploy_staging:
  stage: deploy
  environment: staging
  script:
    - mkdir -p ~/.ssh
    - echo "$STAGING_SSH_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - rsync -avz --delete dist/ staging-server:$APP_DIR/
    - ssh staging-server "cd $APP_DIR && pm2 reload app"
  only:
    - main

cleanup_old:
  stage: cleanup
  script:
    - echo "清理构建缓存..."
    - npm cache clean --force
  when: always

7 Runner 配置

• 注册自定义 Runner:

sudo gitlab-runner register -n \
  --url https://gitlab.com/ \
  --registration-token $REGISTRATION_TOKEN \
  --name docker-runner \
  --executor docker \
  --docker-image alpine:latest \
  --tag-list docker,linux,shared \
  --run-untagged

• 配置示例 `/etc/gitlab-runner/config.toml`:

concurrent = 4

[[runners]]
  name = "docker-runner"
  url = "https://gitlab.com/"
  token = "glrt-xxxxxxx"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "alpine:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

8 总结

通过本教程,您已掌握 GitLab CI/CD 的核心配置技巧,包括:

• 基础流水线结构和语法

• 变量、缓存与制品管理

• 环境部署与动态环境创建

• 条件执行与手动触发

• 完整的 Node.js 项目实战案例

建议从简单流水线开始,逐步添加复杂功能。充分利用 GitLab 内置模板( `.gitlab-ci.yml` → "CI/CD configuration" 模板)和官方文档(https://docs.gitlab.com/ee/ci/)持续优化您的 DevOps 流程。通过自动化,您可以显著减少重复工作,提高发布频率和代码质量。

发表回复

后才能评论