GitLab CI/CD
GitLab CI/CD is the continuous integration and delivery system built into GitLab. Pipelines are defined in a .gitlab-ci.yml file at the repository root and run automatically on pushes, merge requests, tags, schedules, or API triggers. Because it's part of GitLab, pipelines connect directly to merge requests, container and package registries, security scanning, environments, and deployment history — all without third-party integrations.
Jobs run on runners: GitLab-hosted runners on GitLab.com, or self-managed runners on your own VMs, Kubernetes clusters, or bare metal. That flexibility makes GitLab CI a common choice for organizations that self-host GitLab or need builds inside private networks.
TL;DR
- Pipelines live in
.gitlab-ci.yml; they're made of jobs grouped into stages. - Runners execute jobs, typically in Docker containers or Kubernetes pods.
- Control when jobs run with
rules(andworkflow:rulesfor whole pipelines). - Use
needsto build a DAG so jobs start as soon as their dependencies finish. - Cache speeds up dependency installs; artifacts pass build outputs between jobs.
- Model deployments with environments; protect production with protected branches, variables, and approvals.
Quick Example
A pipeline that builds a container, tests in parallel, creates review apps for merge requests, and deploys tagged releases to production:
Core Concepts
Pipelines, Stages, and Jobs
A job is a set of script commands run by a runner. Stages group jobs; by default all jobs in a stage run in parallel and the next stage starts when the previous one succeeds. Pipeline types include branch pipelines, merge request pipelines, merged results pipelines (testing the merge with the target branch), tag pipelines, scheduled pipelines, and parent-child or multi-project pipelines.
Runners and Executors
Tag runners (tags: [gpu]) and select them per job. Self-managed runners keep builds inside private networks.
rules, needs, and DAGs
rules evaluate conditions (branch, source, changed files with changes:, variables) to decide whether a job runs, and whether automatically, manually, or with a delay. needs declares explicit dependencies so a job starts as soon as what it needs is done, ignoring stage boundaries — this can cut pipeline times dramatically.
Cache vs Artifacts
Environments and Deployments
Environments track what's deployed where, with history and one-click rollback to a previous deployment. Dynamic environments create review apps per merge request. Protected environments restrict who can deploy and can require approvals.
Reuse: include, extends, and CI/CD Components
include pulls configuration from files, other projects, templates, or the CI/CD Catalog, where versioned components with typed inputs package reusable pipeline pieces. extends and YAML anchors reduce repetition within a file.
Variables and Secrets
CI/CD variables can be defined per project, group, or instance, masked in logs, and protected so they're only available on protected branches and tags. For cloud credentials, use OIDC ID tokens (id_tokens:) to obtain short-lived credentials instead of storing keys. See Secrets Management.
Best Practices
Use needs for Speed
A DAG pipeline lets fast checks and slow ones proceed independently; the total time becomes the longest path, not the sum of stages.
Run the Right Pipelines
Use workflow:rules to avoid duplicate branch and merge request pipelines, and rules:changes to skip jobs unaffected by a change (valuable in monorepos).
Cache Dependencies by Lockfile
cache:key:files invalidates the cache only when dependencies change.
Protect Production
Deploy only from protected branches or tags, store production secrets in protected variables, and require approvals on protected environments.
Standardize With Components
Publish shared build, test, and security jobs as versioned CI/CD components so every project inherits improvements.
Enable Merged Results Pipelines
Testing the result of merging with the target branch catches integration breaks before they land on main.
Common Mistakes
Duplicate Pipelines
Without workflow:rules, a push to a branch with an open merge request triggers both a branch and an MR pipeline.
Using Cache to Pass Build Outputs
Caches aren't guaranteed. Use artifacts for anything a later job depends on.
Unprotected Secrets
Variables not marked protected are available to every branch, including ones anyone with developer access can push.
Monolithic Stage Ordering
Forcing everything through strict stages when jobs are independent wastes minutes on every pipeline.
latest Images
Unpinned images change without notice. Pin versions or digests.
Comparison
FAQ
What is GitLab CI/CD?
GitLab's built-in system for automatically building, testing, and deploying code, defined in a .gitlab-ci.yml file and run on GitLab runners.
What is a GitLab runner?
An agent that picks up jobs from GitLab and executes them, usually in Docker containers or Kubernetes pods. Runners can be GitLab-hosted or self-managed.
What's the difference between cache and artifacts?
Cache stores reusable files like dependencies to speed up future jobs and isn't guaranteed. Artifacts store job outputs that later jobs or users reliably need, such as build output and test reports.
How do I speed up GitLab pipelines?
Use needs for DAG execution, cache dependencies by lockfile, run tests in parallel with parallel, skip unaffected jobs with rules:changes, and use appropriately sized runners.
GitLab CI or GitHub Actions?
Use the one that matches where your code lives. GitLab CI shines when you use GitLab's integrated registries, security scanning, and environments; GitHub Actions has the larger marketplace.
Related Topics
- CI/CD — Pipeline fundamentals
- GitHub Actions — The GitHub-native alternative
- Docker — Images that jobs run in
- Deployment Strategies — Canary, blue-green, and review apps
- Secrets Management — Protected variables and OIDC