GitLab CI/CD是什么?自动化构建、测试与部署流水线
DevOps

GitLab CI/CD是什么?自动化构建、测试与部署流水线

GitLab CI/CD 是 GitLab 内置的自动化平台,通过 .gitlab-ci.yml 配置文件在每次提交时触发构建、测试和部署流水线。了解 GitLab Runner、流水线结构及最佳实践。

系列文章: DevOps
  1. 1 API网关是什么?微服务的统一入口点
  2. 2 NAT是什么?计算机网络中的网络地址转换详解
  3. 3 GitLab CI/CD是什么?自动化构建、测试与部署流水线
  4. 4 Apache Kafka是什么?分布式事件流处理平台详解
  5. 5 Serverless是什么?FaaS、冷启动与何时选择无服务器架构
  6. 6 Subnet和CIDR是什么?IP网络分段与现代路由
  7. 7 什么是Kubernetes?当今最流行的容器编排平台
  8. 8 Proxy是什么?正向代理、反向代理与SOCKS5详解
  9. 9 什么是Nginx?集Web服务器、反向代理与负载均衡于一体
✦ 快速摘要
GitLab CI/CD 是 GitLab 内置的自动化平台,通过 .gitlab-ci.yml 配置文件在每次提交时触发构建、测试和部署流水线。了解 GitLab Runner、流水线结构及最佳实践。
这篇文章怎么样?

GitLab CI/CD 是内置于 GitLab 平台的流水线自动化系统——无需安装任何外部工具,只需在仓库根目录添加一个 .gitlab-ci.yml 文件,每次提交代码时就会自动触发构建、测试和部署的完整流程。

GitLab CI/CD 是什么?

GitLab CI/CD 是原生内置于 GitLab 的持续集成/持续交付平台,完全由仓库根目录下的 .gitlab-ci.yml 配置文件驱动。每当开发者推送代码或创建 Merge Request,GitLab 自动读取该文件,创建一条由多个 Stage(阶段)顺序执行的 Pipeline(流水线),每个 Stage 内可包含一个或多个并行运行的 Job(作业)。

流水线遵循 test → build → deploy 的经典模式。一旦某个 Job 失败,流水线立即停止并通知开发者——"快速失败"原则确保错误在尽可能早的阶段被捕获,防止问题代码进入生产环境。

GitLab 相较于 Jenkins 等独立 CI/CD 工具的核心优势在于:GitLab 将容器镜像仓库包仓库安全扫描(SAST、DAST)、环境管理部署追踪集成于同一平台,大幅减少了团队需要管理的工具数量。

CI/CD 是什么?持续集成与持续交付概述

.gitlab-ci.yml 的结构

整个流水线在一个 YAML 文件中定义。以下是一个将 Python 应用部署到 Kubernetes 的实际示例:

YAML
 1stages:
 2  - test
 3  - build
 4  - deploy
 5
 6variables:
 7  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
 8
 9# ── 阶段一:运行测试 ───────────────────────────────────────────
10test:
11  stage: test
12  image: python:3.11
13  script:
14    - pip install -r requirements.txt  # 安装依赖
15    - pytest tests/ -v                 # 运行测试
16  cache:
17    key: ${CI_COMMIT_REF_SLUG}
18    paths:
19      - .cache/pip                     # 缓存 pip 包,加速后续运行
20
21# ── 阶段二:构建 Docker 镜像并推送到 GitLab 镜像仓库 ──────────
22build:
23  stage: build
24  image: docker:24
25  services:
26    - docker:dind                      # 启用 Docker-in-Docker
27  script:
28    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
29    - docker build -t $DOCKER_IMAGE .  # 构建镜像
30    - docker push $DOCKER_IMAGE        # 推送到仓库
31  only:
32    - main                             # 仅在 main 分支触发
33
34# ── 阶段三:部署到 Kubernetes(手动确认) ─────────────────────
35deploy:
36  stage: deploy
37  script:
38    - kubectl set image deployment/myapp app=$DOCKER_IMAGE
39  environment:
40    name: production
41  when: manual                         # 需要人工点击确认
42  only:
43    - main

核心概念说明:

  • stages — 声明执行顺序。同一 Stage 内的 Job 并行运行;下一个 Stage 只有在上一个 Stage 全部成功后才会启动。
  • variables — 作用于整个流水线的环境变量。GitLab 还提供内置预定义变量,如 $CI_COMMIT_SHA$CI_REGISTRY_IMAGE$CI_COMMIT_REF_SLUG
  • image — 用作 Job 执行环境的 Docker 镜像,每个 Job 可使用不同的镜像。
  • services — 与 Job 并行运行的辅助容器(例如:docker:dind 允许在容器内构建 Docker 镜像)。
  • cache — 在多次流水线运行之间持久保存的目录,用于加速构建(.cache/pipnode_modules/)。
  • artifacts — Job 产生的输出文件,可传递给下游 Job 或在流水线完成后供下载。
  • only / rules — 控制 Job 触发条件(仅在 main 分支运行、仅在打 tag 时运行等)。
  • when: manual — Job 不会自动运行,需要有权限的人员在界面点击执行按钮——适合生产环境部署的审批门控。
  • environment — 将 Job 关联到 GitLab Environments 中的命名环境,支持部署历史追踪和一键回滚。

GitLab Runner

GitLab Runner 是安装在服务器(或容器/Kubernetes Pod)上的代理软件,负责从 GitLab 服务器接收 Job 并执行。Runner 持续轮询 GitLab,接收分配的 Job,克隆源代码,在已配置的执行器中运行脚本,最后将日志和退出码返回给 GitLab。

共享 Runner 与专用 Runner

共享 Runner 专用 Runner
管理方 GitLab(或组管理员) 您的团队
使用范围 实例内所有项目 特定项目或群组
资源 共享,高峰期可能排队 独享,无需排队
费用 按 CI 分钟计费 自有服务器成本
适合场景 小型项目、公共仓库 重度生产工作负载

Docker 执行器——最常用的选择

Docker 执行器在全新的 Docker 容器中运行每个 Job,确保每次运行的环境完全隔离且干净。这是大多数场景下推荐的执行器。

使用 Docker 执行器注册专用 Runner:

Bash
 1# 在 Ubuntu/Debian 上安装 GitLab Runner
 2curl -L --output /usr/local/bin/gitlab-runner \
 3  "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64"
 4chmod +x /usr/local/bin/gitlab-runner
 5
 6# 注册 Runner(在 Settings → CI/CD → Runners 获取 Token)
 7gitlab-runner register \
 8  --url "https://gitlab.com/" \
 9  --registration-token "YOUR_REGISTRATION_TOKEN" \
10  --executor "docker" \
11  --docker-image "alpine:latest" \
12  --description "my-docker-runner" \
13  --tag-list "docker,production"

注册完成后,Runner 出现在 Settings → CI/CD → Runners 中并开始接收 Job。使用**标签(tag)**将特定 Job 路由到特定 Runner——例如,生产部署 Job 只允许在打了 production 标签、部署在内网的 Runner 上执行。

Kubernetes 是什么?大规模容器编排

GitLab vs GitHub Actions vs Jenkins

对比维度 GitLab CI/CD GitHub Actions Jenkins
配置复杂度 低(内置) 低(内置) 高(需安装配置)
免费自托管 是(GitLab CE) 否(需 GitHub Enterprise) 是(开源)
免费云端额度 400 分钟/月 2,000 分钟/月
内置容器镜像仓库 是(GHCR)
内置安全扫描 是(SAST/DAST) 部分(CodeQL) 插件
配置语法 YAML (.gitlab-ci.yml) YAML (.github/workflows/) Groovy (Jenkinsfile)
市场/插件生态 GitLab 模板 20,000+ Actions 1,800+ 插件
最适合 自托管、一体化平台 GitHub 生态 企业本地部署

何时选择 GitLab CI/CD:

  • 项目需要将整个技术栈(代码 + CI/CD + 镜像仓库)自托管于本地环境。
  • 团队需要在同一平台内整合安全扫描、合规管理和审计追踪。
  • 金融科技、银行、医疗健康等行业需要 100% 的数据主权,所有数据必须保留在内部服务器。

何时选择 GitHub Actions:

  • 仓库已在 GitHub 上,希望零配置接入流水线。
  • 开源项目需要充裕的免费 CI 分钟数。
  • 需要与 GitHub 生态深度集成(Dependabot、CodeQL、GitHub Packages)。

何时选择 Jenkins:

  • 已在 Jenkins 插件和 Groovy 流水线上积累大量投资的传统企业环境。
  • 需要与多种代码管理系统集成(Bitbucket Server、Perforce、SVN)。

最佳实践

1. 缓存依赖以加速构建

YAML
 1# Python——缓存 pip 包
 2cache:
 3  key: ${CI_COMMIT_REF_SLUG}-pip
 4  paths:
 5    - .cache/pip
 6  policy: pull-push
 7
 8# Node.js——缓存 node_modules
 9cache:
10  key:
11    files:
12      - package-lock.json
13  paths:
14    - node_modules/

对于只读缓存的 Job,使用 policy: pull,避免每次 Job 结束后不必要的缓存上传。

2. 使用 needs: 实现并行化(DAG 流水线)

YAML
 1test-unit:
 2  stage: test
 3  script: pytest tests/unit/       # 运行单元测试
 4
 5test-integration:
 6  stage: test
 7  script: pytest tests/integration/ # 运行集成测试
 8
 9build:
10  stage: build
11  needs: [test-unit]               # test-unit 完成即可开始,无需等待 test-integration
12  script: docker build .

needs: 打破了传统的顺序 Stage 模型,让 build Job 在 test-unit 完成后立即启动,无需等待 test-integration,从而显著缩短流水线总耗时。

3. 保护生产环境

Settings → CI/CD → Environments → production 中配置:

  • 必要审批人数:生产部署需至少 1-2 名指定审批人确认。
  • 受保护分支:仅 mainrelease/* 分支可触发生产部署。
  • 部署冻结期:在流量高峰或重要假日期间禁止部署。

4. 启用内置 SAST 扫描

YAML
1include:
2  - template: Security/SAST.gitlab-ci.yml  # 引入官方 SAST 模板
3
4sast:
5  stage: test
6  variables:
7    SAST_EXCLUDED_PATHS: "tests/, docs/"   # 排除测试和文档目录

GitLab SAST 会自动为项目使用的语言选择合适的分析器(Python 使用 Bandit、JS/TS 使用 Semgrep、Java 使用 SpotBugs),无需额外配置。

5. 为生产部署设置手动审批门控

始终将 when: manualenvironment: production 结合使用。这在 GitLab 界面中创建了一个清晰的确认按钮,并记录完整的审计日志——谁触发了部署以及触发时间。

微服务是什么?分布式架构与实际应用

实际应用场景

初创企业——快速启动,无需专职运维

初创企业可以免费使用 GitLab.com(每月 400 分钟),配置一条基础的三阶段流水线:测试 → 构建 Docker 镜像 → 通过 SSH 部署到 VPS。所有配置集中在一个 .gitlab-ci.yml 文件中,从第一天起就无需专职 DevOps 工程师。随着规模扩大,只需对现有流水线结构做最小改动即可升级为 Kubernetes 部署。

银行与金融科技——自托管满足合规要求

金融机构需要将源代码、制品和日志完全保留在自有基础设施中。自托管 GitLab CE 实例提供:

  • 无流水线分钟限制 — 在内部服务器上自由运行流水线。
  • 数据不离开数据中心 — 源代码、Docker 镜像和流水线日志均保存在内部服务器。
  • 完整审计日志 — GitLab 记录每一个操作:谁提交了代码、谁批准了 Merge Request、谁触发了部署以及触发时间。
  • 集成 SAST 和密钥检测 — 意外提交到仓库的凭证信息在流水线内即刻被标记。

核心银行系统的典型流水线:sast → 单元测试 → 集成测试 → 构建镜像 → 推送到内部镜像仓库 → 部署预生产环境(自动)→ 部署生产环境(手动,需2人审批)

总结: 当您需要一个一体化平台——从代码管理到 CI/CD、容器镜像仓库和安全扫描——尤其是对数据主权要求严格的自托管项目,GitLab CI/CD 是极具竞争力的选择。从一个简单的 .gitlab-ci.yml 开始,随着团队成熟度的提升,逐步引入缓存、并行 Job 和手动审批门控。

常见问题

常见问题Q&A
GitLab CI/CD 和 GitHub Actions 有什么区别?
GitLab CI/CD 内置于 GitLab 平台,通过 .gitlab-ci.yml 配置,可运行在 GitLab.com(云端)或自托管实例上。GitHub Actions 与 GitHub 深度集成,使用类似的 YAML 语法,但以 workflow/job 替代 stages/jobs 的概念。主要区别在于:GitLab 在同一平台内集成了容器镜像仓库(Container Registry)、包仓库(Package Registry)和安全扫描(SAST/DAST);GitHub Actions 拥有更丰富的 Marketplace,且公共仓库的免费分钟数更多。需要将数据保留在本地的金融机构和银行通常选择 GitLab CE/EE,因为其私有化部署更为便捷。
GitLab Runner 是什么?
GitLab Runner 是安装在独立服务器(或容器/Kubernetes Pod)上的代理程序,负责轮询 GitLab 获取待执行的 Job 并运行它们。Runner 接收到 Job 后,拉取源代码,在已配置的执行器环境(Shell、Docker、Kubernetes、VirtualBox 等)中运行脚本,最后将日志和退出码返回给 GitLab。GitLab.com 提供共享 Runner,免费使用但有每月分钟限制;您也可以在自己的服务器上注册专用 Runner,获得完全的资源控制权且无分钟限制。
.gitlab-ci.yml 应该放在哪里?
.gitlab-ci.yml 文件必须放在仓库根目录下,与 README.md 和其他配置文件并列。GitLab 会在每次 push 或 Merge Request 事件时自动检测该文件。您可以在提交前通过浏览器内置的 CI Lint 工具(Settings → CI/CD → CI Lint)验证 YAML 语法。GitLab 还支持通过 include: 关键字将配置拆分为多个文件,从其他项目或内置的 GitLab CI/CD 模板库中引入模板。
流水线的 Job 可以并行运行吗?
可以。GitLab CI/CD 支持两种并行化方式:(1) 同一 Stage 内的 Job 在有足够 Runner 时默认并行运行。(2) needs: 关键字允许声明 Job 间的依赖关系——Job B 可以在 Job A 完成后立即启动,无需等待整个 Stage 结束,这称为 DAG(有向无环图)流水线。此外,parallel: matrix: 允许同一个 Job 以不同变量组合并行运行,非常适合跨浏览器测试或多版本兼容性测试。
GitLab CI 免费吗?
GitLab.com 的 Free 套餐每月提供 400 分钟共享 Runner CI/CD 时长。Premium 和 Ultimate 套餐提供更多分钟数及高级功能(完整 DAST、SAST、合规框架等)。如果您在自己的服务器上自托管 GitLab 社区版(CE),则没有分钟限制——使用量仅受服务器资源约束。这也是许多企业选择自托管 GitLab CE 的原因:无许可证费用,且流水线运行不受分钟限制。
GitLab CI 中 Artifact 和 Cache 有什么区别?
Artifact(制品)是 Job 产生的输出文件,由 GitLab 服务器保存并传递给下游 Job,或在流水线完成后供下载(例如已编译的二进制文件、测试报告)。Cache(缓存)是在多次流水线运行之间持久保存的目录(通常是 node_modules/ 或 .cache/pip),通过跳过重复的依赖下载来加速构建。Artifact 由 GitLab 服务器管理并支持过期策略;Cache 直接存储在 Runner 上,随时可能失效,因此您的流水线不应依赖 Cache 的存在来保证正确运行。

GitLab CI/CD is a pipeline automation system built directly into the GitLab platform — no external tools required. A single .gitlab-ci.yml file in the repository is all it takes to trigger a fully automated build, test, and deploy workflow on every commit.

What is GitLab CI/CD?

GitLab CI/CD is a Continuous Integration / Continuous Delivery platform embedded natively in GitLab, driven entirely by a .gitlab-ci.yml configuration file placed at the repository root. Every time a developer pushes code or opens a merge request, GitLab reads this file, creates a pipeline composed of sequential stages, and runs one or more jobs in parallel within each stage.

A pipeline follows the pattern: test → build → deploy. If any job fails, the pipeline stops immediately and notifies the developer — the "fail fast" principle ensures errors are caught as early as possible, before broken code reaches production.

The key advantage of GitLab over standalone CI/CD tools like Jenkins is that GitLab bundles a Container Registry, Package Registry, Security Scanning (SAST, DAST), Environments, and Deployment tracking in one platform — dramatically reducing the number of tools your team needs to manage.

What is CI/CD? Overview of Continuous Integration and Delivery

Structure of .gitlab-ci.yml

The entire pipeline is defined in a single YAML file. The following is a real-world example for a Python application deployed to Kubernetes:

YAML
 1stages:
 2  - test
 3  - build
 4  - deploy
 5
 6variables:
 7  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
 8
 9# ── Stage 1: Run tests ─────────────────────────────────────────
10test:
11  stage: test
12  image: python:3.11
13  script:
14    - pip install -r requirements.txt
15    - pytest tests/ -v
16  cache:
17    key: ${CI_COMMIT_REF_SLUG}
18    paths:
19      - .cache/pip
20
21# ── Stage 2: Build Docker image and push to GitLab Registry ───
22build:
23  stage: build
24  image: docker:24
25  services:
26    - docker:dind
27  script:
28    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
29    - docker build -t $DOCKER_IMAGE .
30    - docker push $DOCKER_IMAGE
31  only:
32    - main
33
34# ── Stage 3: Deploy to Kubernetes (manual gate) ───────────────
35deploy:
36  stage: deploy
37  script:
38    - kubectl set image deployment/myapp app=$DOCKER_IMAGE
39  environment:
40    name: production
41  when: manual
42  only:
43    - main

Key concepts explained:

  • stages — declares the execution order. Jobs in the same stage run in parallel; the next stage only starts when the previous one succeeds.
  • variables — environment variables available across the pipeline. GitLab also provides built-in predefined variables such as $CI_COMMIT_SHA, $CI_REGISTRY_IMAGE, and $CI_COMMIT_REF_SLUG.
  • image — the Docker image used as the job execution environment. Each job can use a different image.
  • services — auxiliary containers running alongside the job (for example: docker:dind enables Docker-in-Docker to build images inside a container).
  • cache — directories persisted between pipeline runs to speed up builds (.cache/pip, node_modules/).
  • artifacts — output files passed to downstream jobs or downloadable after the pipeline finishes.
  • only / rules — conditions controlling when a job runs (only on the main branch, only on tags, etc.).
  • when: manual — the job does not run automatically; someone with permission must click the play button — ideal for production deploy gates.
  • environment — links the job to a named environment in GitLab Environments, enabling deployment history tracking and one-click rollback.

GitLab Runner

GitLab Runner is a software agent installed on a server (or running inside a container or Kubernetes pod) that accepts jobs from the GitLab server and executes them. The runner continuously polls GitLab, picks up assigned jobs, clones the source code, runs the pipeline scripts inside the configured executor, and sends logs and exit codes back to GitLab.

Shared Runner vs Specific Runner

Shared Runner Specific Runner
Managed by GitLab (or group admin) Your team
Scope All projects in the instance A specific project or group
Resources Shared, may queue under load Dedicated, no queueing
Cost Billed per CI minute Cost of your own server
Best for Small projects, public repos Heavy production workloads

The Docker executor runs each job inside a fresh Docker container, guaranteeing a fully isolated and clean environment for every run. This is the recommended executor for most use cases.

Registering a specific runner with the Docker executor:

Bash
 1# Install GitLab Runner on Ubuntu/Debian
 2curl -L --output /usr/local/bin/gitlab-runner \
 3  "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64"
 4chmod +x /usr/local/bin/gitlab-runner
 5
 6# Register the runner (get the token from Settings → CI/CD → Runners)
 7gitlab-runner register \
 8  --url "https://gitlab.com/" \
 9  --registration-token "YOUR_REGISTRATION_TOKEN" \
10  --executor "docker" \
11  --docker-image "alpine:latest" \
12  --description "my-docker-runner" \
13  --tag-list "docker,production"

After registration the runner appears in Settings → CI/CD → Runners and is ready to accept jobs. Use tags to route specific jobs to specific runners — for example, the production deploy job can be restricted to a runner tagged production that lives inside the internal network.

What is Kubernetes? Container Orchestration at Scale

GitLab vs GitHub Actions vs Jenkins

Criterion GitLab CI/CD GitHub Actions Jenkins
Setup complexity Low (built-in) Low (built-in) High (install & configure)
Free self-hosting Yes (GitLab CE) No (GitHub Enterprise) Yes (open-source)
Free cloud tier 400 min/month 2,000 min/month N/A
Built-in Container Registry Yes Yes (GHCR) No
Built-in Security Scanning Yes (SAST/DAST) Partial (CodeQL) Plugin
Config syntax YAML (.gitlab-ci.yml) YAML (.github/workflows/) Groovy (Jenkinsfile)
Marketplace / Plugins GitLab Templates 20,000+ Actions 1,800+ Plugins
Best for Self-host, all-in-one GitHub ecosystem Enterprise on-premise

When to choose GitLab CI/CD:

  • The project needs to self-host the entire stack (code + CI/CD + registry) on-premise.
  • The team requires security scanning, compliance, and audit trails within a single platform.
  • Fintech, banking, or healthcare organizations that must keep 100% of data on internal servers.

When to choose GitHub Actions:

  • The repository is already on GitHub and you want zero-configuration pipelines.
  • Open-source projects that need generous free CI minutes.
  • You need tight integration with the GitHub ecosystem (Dependabot, CodeQL, GitHub Packages).

When to choose Jenkins:

  • Legacy enterprise environments with heavy investment in Jenkins plugins and Groovy pipelines.
  • Scenarios requiring integration with multiple SCM systems (Bitbucket Server, Perforce, SVN).

Best Practices

1. Cache dependencies to speed up builds

YAML
 1# Python — cache pip packages
 2cache:
 3  key: ${CI_COMMIT_REF_SLUG}-pip
 4  paths:
 5    - .cache/pip
 6  policy: pull-push
 7
 8# Node.js — cache node_modules
 9cache:
10  key:
11    files:
12      - package-lock.json
13  paths:
14    - node_modules/

Use policy: pull on jobs that only read the cache (no need to re-upload) to avoid unnecessary uploads at the end of every job.

2. Parallelize with needs: (DAG pipelines)

YAML
 1test-unit:
 2  stage: test
 3  script: pytest tests/unit/
 4
 5test-integration:
 6  stage: test
 7  script: pytest tests/integration/
 8
 9build:
10  stage: build
11  needs: [test-unit]  # Starts as soon as test-unit passes, no need to wait for test-integration
12  script: docker build .

needs: breaks the traditional sequential stage model, allowing the build job to begin immediately after test-unit finishes without waiting for test-integration — significantly reducing total pipeline duration.

3. Protect production environments

In Settings → CI/CD → Environments → production, configure:

  • Required approvals: production deploys require approval from at least one or two designated reviewers.
  • Protected branches: only main or release/* branches can trigger production deployments.
  • Deployment freeze: block deployments during peak traffic hours or major holidays.

4. Enable built-in SAST scanning

YAML
1include:
2  - template: Security/SAST.gitlab-ci.yml
3
4sast:
5  stage: test
6  variables:
7    SAST_EXCLUDED_PATHS: "tests/, docs/"

GitLab SAST automatically selects the appropriate analyzer for the project's language (Bandit for Python, Semgrep for JS/TS, SpotBugs for Java) with no additional configuration required.

5. Manual gate for production deployments

Always combine when: manual with environment: production on deploy jobs. This creates a clear confirmation button in the GitLab UI with a full audit trail recording who triggered the deployment and when.

What is Microservices? Distributed Architecture in Practice

Real-World Use Cases

Startup — fast setup, no dedicated ops team

A startup can use GitLab.com for free (400 minutes/month) with a basic three-stage pipeline: test → build Docker image → deploy to a VPS via SSH. The entire configuration lives in a single .gitlab-ci.yml file — no dedicated DevOps engineer needed from day one. As the team scales, upgrading to a Kubernetes deploy step requires minimal changes to the existing pipeline structure.

Banking and Fintech — self-hosted for compliance

Financial institutions need to keep source code, artifacts, and logs entirely within their own infrastructure. A self-managed GitLab CE instance delivers:

  • No CI minute caps — pipelines run freely on internal servers.
  • Data never leaves the datacenter — source code, Docker images, and pipeline logs stay on internal servers.
  • Complete audit trail — GitLab logs every action: who committed, who approved the merge request, who triggered the deploy, and when.
  • Integrated SAST and Secret Detection — credentials accidentally committed to the repository are flagged immediately within the pipeline.

A typical pipeline for a core banking system: sast → unit-test → integration-test → build-image → push-to-internal-registry → deploy-staging (auto) → deploy-production (manual, requires 2 approvals).

Conclusion: GitLab CI/CD is a compelling choice when you need an all-in-one platform — from source code management to CI/CD, container registry, and security scanning — especially for self-hosted projects with strict data control requirements. Start with a simple .gitlab-ci.yml, then progressively add caching, parallel jobs, and manual gates as your team matures.

Frequently Asked Questions

Frequently Asked QuestionsQ&A
How is GitLab CI/CD different from GitHub Actions?
GitLab CI/CD is built directly into the GitLab platform, configured via a .gitlab-ci.yml file and runnable on GitLab.com (cloud) or a self-managed instance. GitHub Actions is tightly integrated with GitHub and uses a similar YAML syntax but organizes work into workflows and jobs rather than stages and jobs. Key differences: GitLab ships a built-in Container Registry, Package Registry, and security scanning (SAST/DAST) in the same platform; GitHub Actions has a much larger marketplace of reusable actions and more free minutes for public repos. Organizations that must keep data on-premise (fintech, banking) often choose GitLab CE/EE because it is straightforward to self-host.
What is a GitLab Runner?
A GitLab Runner is an agent process installed on a separate server (or running inside a container or Kubernetes pod) that polls GitLab for pending jobs and executes them. The runner picks up a job, clones the source code, runs the script inside the configured executor environment (Shell, Docker, Kubernetes, VirtualBox, etc.), and reports logs and the exit code back to GitLab. GitLab.com provides shared runners free of charge up to a monthly minute limit; you can register a specific runner on your own server for full control over resources with no minute cap.
Where should .gitlab-ci.yml be placed?
The .gitlab-ci.yml file must be placed at the root of the repository, alongside README.md and other configuration files. GitLab automatically detects it on every push or merge request event. You can validate the YAML syntax directly in the browser using the CI Lint tool (Settings → CI/CD → CI Lint) before committing. GitLab also supports splitting the configuration into multiple files using the include: keyword to import templates from other projects or from the built-in GitLab CI/CD template library.
Can pipeline jobs run in parallel?
Yes. GitLab CI/CD supports parallelism in two ways: (1) Jobs within the same stage run in parallel by default whenever enough runners are available. (2) The needs: keyword lets you declare explicit dependencies between jobs — job B can start as soon as job A finishes without waiting for the entire stage to complete. This is called a DAG (Directed Acyclic Graph) pipeline. Additionally, parallel: matrix: allows running the same job with different variable combinations simultaneously, which is ideal for cross-browser or multi-version testing.
Is GitLab CI free to use?
GitLab.com offers a Free tier with 400 CI/CD minutes per month on shared runners. Premium and Ultimate tiers provide more minutes and advanced features (full DAST, SAST, compliance frameworks, etc.). If you self-host GitLab Community Edition (CE) on your own server, there is no minute cap — usage is only limited by your server resources. This is why many organizations choose self-hosted GitLab CE: no license cost and no pipeline minute restrictions.
What is the difference between artifacts and cache in GitLab CI?
Artifacts are output files produced by a job that GitLab stores and passes to downstream jobs or makes available for download after the pipeline completes (for example: compiled binaries, test reports). Cache is a directory saved between pipeline runs (typically node_modules/ or .cache/pip) to speed up builds by skipping repeated dependency downloads. Artifacts are managed by the GitLab server and support expiry policies; cache is stored directly on the runner and can be invalidated at any time, so your pipeline must never depend on the cache being present to run correctly.