Disclaimer: ChatGPT generated document.
GitLab can feel confusing to a beginner because several different systems are presented through one interface.
A repository lives in GitLab. A pipeline is defined in GitLab. Jobs appear in GitLab. Logs appear in GitLab. Yet the commands in those jobs may actually execute on another computer, inside a virtual machine, a Docker container, or even a Kubernetes cluster.
Understanding GitLab CI/CD becomes much easier once those responsibilities are separated.
This article builds that mental model from the ground up. References to official GitLab, Docker, and Kubernetes documentation are included throughout, followed by a reference guide at the end.
At the simplest level, GitLab can host a Git repository:
Developer
│
│ git push
▼
GitLab repository
GitLab also provides systems around repositories, including merge requests, issues, code review, package and container registries, releases, security features, and CI/CD.
CI/CD stands for:
Continuous Integration
and
Continuous Delivery / Continuous Deployment
A simple continuous-integration workflow might look like:
Developer pushes code
│
▼
GitLab creates a pipeline
│
▼
Compile
│
▼
Run tests
│
▼
Report success or failure
The important point is that GitLab coordinates this process automatically.
GitLab CI/CD pipelines are normally described in a file stored in the repository:
.gitlab-ci.yml
For example:
stages:
- build
- test
build:
stage: build
script:
- cmake -S . -B build
- cmake --build build
test:
stage: test
script:
- ctest --test-dir buildThis file tells GitLab what work should happen.
It does not itself provide the computer that performs the work.
A useful analogy is:
.gitlab-ci.yml = recipe
runner = kitchen
The distinction between pipeline definition and execution infrastructure is fundamental to understanding GitLab CI/CD.
A pipeline is the complete CI/CD workflow created by GitLab.
A stage groups jobs into broad phases.
A job is an individual unit of executable work.
For example:
Pipeline
│
├── Stage: build
│ ├── build-gcc
│ └── build-clang
│
├── Stage: test
│ ├── unit-tests
│ └── integration-tests
│
└── Stage: deploy
└── publish
A job eventually needs a machine or execution environment on which its commands can run.
That is where GitLab Runner enters the picture.
GitLab Runner is software that accepts CI/CD jobs and executes them.
A simplified architecture is:
GitLab
│
│ assigns job
▼
GitLab Runner
│
│ prepares environment
▼
Job commands execute
│
▼
Result returned to GitLab
The runner typically performs tasks such as retrieving the repository, preparing the environment, executing the script commands, handling caches and artifacts, and reporting success or failure.
An important distinction is therefore:
GitLab orchestrates CI/CD, while a runner performs the actual work.
GitLab's official runner documentation is the best starting reference for this concept. (GitLab Docs)
Two terms are easy to confuse:
Runner
and
Executor
They are not interchangeable.
The runner answers:
Which worker accepts this job?
The executor answers:
How does that runner execute the job?
For example:
GitLab
│
▼
GitLab Runner
│
└── Docker executor
│
▼
Container
Another runner could use:
GitLab
│
▼
GitLab Runner
│
└── Kubernetes executor
│
▼
Kubernetes Pod
Or:
GitLab
│
▼
GitLab Runner
│
└── Shell executor
│
▼
Host OS
The executor is therefore part of the runner's execution strategy.
With a GitLab-hosted runner, GitLab supplies and manages the compute infrastructure.
For a GitLab.com user, the conceptual architecture is:
Repository
│
▼
GitLab.com
│
▼
GitLab-hosted runner infrastructure
│
▼
CI job
GitLab-hosted runners are enabled by default for GitLab.com projects and can execute Linux, Windows, macOS, Arm, and some specialized workloads depending on availability and tier. (GitLab Docs)
The advantage is that the user does not need to administer the underlying runner fleet.
GitLab handles much of the infrastructure work such as provisioning and maintaining machines.
GitLab's current hosted Linux runner architecture uses a fresh virtual machine for each CI/CD job.
Conceptually:
Job becomes ready
│
▼
Provision temporary VM
│
▼
Prepare CI environment
│
▼
Execute job
│
▼
Upload results
│
▼
Destroy VM
The VM is dedicated to that specific job rather than being a permanently shared working directory between unrelated jobs. (GitLab Docs)
This design provides strong job isolation and makes CI environments more disposable.
A virtual machine and a container are not the same abstraction.
A simplified virtual-machine model is:
Physical/cloud server
│
├── Virtual machine
│ └── Guest operating system
│
└── Virtual machine
└── Guest operating system
Containers are lighter-weight:
Host operating system
│
├── Container A
├── Container B
└── Container C
Containers generally share the host kernel while isolating application processes, filesystems, networking, and other resources.
Docker describes a container as an isolated process created from a container image. (Docker Documentation)
Virtual machines and containers can also be combined. A CI provider might create an ephemeral VM and then run containers inside that VM.
Docker provides a way to package an execution environment into an image.
An image might contain:
Linux userland
GCC
CMake
Ninja
Python
Git
libraries
other dependencies
A container is a running instance of such an image.
For example:
build:
image: gcc:15
script:
- gcc --version
- cmake -S . -B build
- cmake --build buildConceptually:
Runner
│
▼
Obtain gcc:15 image
│
▼
Create container
│
▼
Execute build
Docker's official introduction explains images, containers, the Docker daemon, registries, and the client/server architecture in more detail. (Docker Documentation)
Without containers, a pipeline may depend on whatever happens to be installed on a runner machine:
Runner machine
│
├── GCC ???
├── CMake ???
└── Python ???
Someone upgrades GCC, and suddenly the build environment has changed.
With an explicitly selected image:
Pipeline
│
▼
Known container image
│
▼
Known tooling
the environment becomes more reproducible.
The same image can often be used locally and in CI:
Developer workstation ──► same image
CI runner ──► same image
This helps reduce environmental differences between developers and automated builds.
Docker's beginner documentation specifically emphasizes consistent, isolated environments as one of the major benefits of containers. (Docker Documentation)
Several Docker-related CI concepts are frequently confused.
Runner
│
▼
Container
│
▼
Build and test
This is ordinary containerized execution.
A job might itself run:
docker build .
That means Docker is being used to produce an image.
Docker-in-Docker, often abbreviated DinD, usually involves a Docker client inside the CI environment communicating with another Docker daemon.
Conceptually:
CI job
│
▼
Docker client
│
▼
Docker daemon
│
▼
Build/run containers
These are three different architectural situations.
Using a Docker executor does not automatically imply that Docker-in-Docker is necessary.
A Shell executor executes job commands directly on the machine where GitLab Runner is installed.
GitLab
│
▼
Runner
│
▼
Host operating system
│
├── compiler
├── CMake
└── other tools
This is conceptually simple but offers much less environmental isolation.
One job may leave files or state behind that can affect another job.
Dependencies must also be installed and maintained directly on the runner machine.
For this reason, containerized execution is often easier to make reproducible.
Instead of using GitLab-provided compute infrastructure, an organization can install GitLab Runner on a machine it controls.
For example:
GitLab.com
│
▼
Company server
│
▼
GitLab Runner
That server might be a cloud VM, physical server, workstation, ARM device, Windows computer, macOS machine, or hardware connected to specialized equipment.
A self-managed runner becomes attractive when a workload needs something special, such as:
GPU
ARM hardware
proprietary compiler
special SDK
private corporate network
USB hardware
licensed engineering software
The tradeoff is responsibility.
The organization now has to think about:
OS updates
security
runner upgrades
networking
disk capacity
machine failures
monitoring
credentials
scaling
The general infrastructure principle is:
more control
│
▼
more responsibility
GitLab also classifies runners based on their scope.
An instance runner can serve projects across a GitLab instance.
A group runner can serve projects and subgroups belonging to a particular group.
A project runner is associated with specific projects.
Conceptually:
GitLab instance
│
├── Instance runner
│
├── Group
│ ├── Group runner
│ ├── Project A
│ └── Project B
│
└── Project C
└── Project runner
This makes it possible for organizations to share or restrict execution infrastructure according to organizational boundaries. (GitLab Docs)
The word namespace appears frequently in GitLab documentation.
A namespace is an organizational container used for projects.
GitLab primarily distinguishes between user namespaces and group namespaces. (GitLab Docs)
Suppose a user named Alice creates:
alice/calculator
Then:
alice
is the personal namespace.
A company could instead have:
example-company/backend
example-company/frontend
example-company/mobile
Here:
example-company
is a group namespace.
Groups may also contain subgroups:
example-company
│
├── products
│ ├── desktop
│ └── mobile
│
└── infrastructure
├── deployment
└── monitoring
Namespaces become important because subscriptions, permissions, and compute accounting can apply at the top-level namespace level.
Imagine:
company
│
└── products
│
└── desktop
│
└── application
The top-level group is:
company
Even though a project may exist several levels deeper, GitLab can associate subscription and compute information with that top-level group.
For GitLab.com paid subscriptions, GitLab states that the subscription applies to a top-level group, and members of projects and subgroups inherit access to the features of that subscription. (GitLab Docs)
Executing CI jobs consumes real computing resources:
CPU
RAM
storage
network
machine time
GitLab measures use of its managed runner capacity through compute minutes.
The simplified intuition is:
job runs for 5 minutes
≈
some quantity of compute usage
But GitLab does not simply count wall-clock minutes.
The current formula is:
Compute usage
=
job duration / 60
×
cost factor
where job duration is measured in seconds. (GitLab Docs)
A cost factor lets GitLab account differently for different runner sizes and platforms.
Consider:
Runner A
2 vCPU
8 GB RAM
versus:
Runner B
32 vCPU
128 GB RAM
One minute on those machines does not represent the same amount of infrastructure.
For GitLab.com's current hosted Linux x86-64 runners, for example, GitLab documents cost factors ranging from 1 on a small runner to 12 on a 2xlarge runner. (GitLab Docs)
Therefore:
A compute minute is better thought of as normalized compute consumption than as a literal stopwatch minute.
Imagine three jobs:
build
test
documentation
Each needs ten minutes.
If they run sequentially:
build 10 min
test 10 min
docs 10 min
the pipeline takes approximately 30 minutes.
If they run simultaneously:
build ██████████
test ██████████
docs ██████████
the pipeline might complete in approximately ten minutes of wall-clock time.
But three jobs have each consumed runner resources for ten minutes.
Therefore:
pipeline duration
≠
total compute usage
GitLab explicitly documents that the compute usage of a pipeline is the total of its jobs and that concurrent execution can therefore consume more compute minutes than the end-to-end duration of the pipeline. (GitLab Docs)
A CI job can wait because no compatible runner is available.
For example:
5 minutes pending
3 minutes executing
GitLab's compute calculation uses the actual job execution duration and excludes time spent in created or pending states. (GitLab Docs)
So waiting for capacity and consuming capacity are distinct concepts.
GitLab.com namespaces receive a monthly quantity of included hosted compute according to their subscription.
As of August 2026, GitLab's pricing page lists:
| Tier | Included compute minutes/month |
|---|---|
| Free | 400 |
| Premium | 10,000 |
| Ultimate | 50,000 |
(GitLab)
GitLab tracks that usage against the job's top-level namespace. (GitLab Docs)
Imagine a namespace with several projects:
company
│
├── project-a
├── project-b
└── project-c
They draw from the namespace's compute quota rather than each automatically receiving an independent full subscription quota.
The regular monthly usage resets each month. (GitLab Docs)
Additional compute minutes can also be purchased for GitLab.com groups. (GitLab Docs)
If GitLab provides the runner infrastructure, GitLab must meter the resource being consumed.
If you provide your own runner infrastructure, the cost moves elsewhere.
Instead of:
GitLab hosted-compute consumption
you may now have:
AWS bill
Azure bill
Google Cloud bill
server purchase
electricity
maintenance
administration
Therefore:
A self-managed runner is not necessarily free.
It means that you or your organization provide the computing resources.
Two GitLab concepts should also be kept separate:
Offering
and
Tier
An offering describes how GitLab itself is provided.
A tier describes which product features and allowances are included.
GitLab currently distinguishes among GitLab.com, GitLab Self-Managed, and GitLab Dedicated. (GitLab Docs)
GitLab.com is GitLab's software-as-a-service offering.
GitLab operates the infrastructure.
A user creates an account and begins using GitLab without installing the GitLab server software.
Conceptually:
GitLab operates GitLab itself
│
▼
User accesses GitLab.com
This is usually the simplest way to start learning GitLab.
With GitLab Self-Managed, an organization installs and operates GitLab itself.
Organization infrastructure
│
▼
GitLab installation
│
├── repositories
├── users
├── CI coordination
└── other GitLab services
The organization becomes responsible for installation, upgrades, availability, security, backup, and infrastructure.
This gives significantly more control but also significantly more operational responsibility. (GitLab Docs)
GitLab Dedicated is GitLab's single-tenant SaaS offering, primarily aimed at large organizations and environments with stronger regulatory or isolation requirements. (GitLab Docs)
It is useful to know that it exists, but it is not generally something a beginner needs in order to learn GitLab CI/CD.
GitLab's main subscription tiers are:
Free
Premium
Ultimate
The Free tier provides the foundation of GitLab development and CI/CD functionality.
Premium adds capabilities intended for larger teams and more advanced development workflows.
Ultimate adds further security, compliance, governance, and enterprise functionality.
The current GitLab pricing page provides the authoritative comparison of these tiers. (GitLab)
Because pricing and feature boundaries change, these details should always be verified before making purchasing decisions.
Several current limits are useful examples of what a subscription tier can affect.
For GitLab.com Free, GitLab currently provides 400 hosted compute minutes per month. (GitLab Docs)
Private top-level groups on the Free tier currently have a five-user limit. (GitLab Docs)
Free GitLab.com projects currently receive 10 GiB of repository and Git LFS storage per project. (GitLab Docs)
These are GitLab product limits, not limitations of Git itself.
Git has no concept of:
GitLab Free
GitLab Premium
compute minutes
GitLab subscription seats
Those concepts belong to the GitLab platform.
GitLab-hosted runners can have different amounts of CPU, RAM, and storage.
Larger runners can make CPU- or memory-intensive workloads faster, but they can also consume quota at a greater cost factor.
That creates an engineering tradeoff:
faster job
│
versus
│
higher compute consumption
Therefore, the goal is not automatically to use the largest available runner.
A better objective is:
use enough resources
to achieve acceptable feedback time
without unnecessary cost
Current runner types and cost factors are documented by GitLab in its hosted-runner and compute-minute documentation. (GitLab Docs)
These concepts solve different problems.
A cache generally exists to make future jobs faster.
Typical cache contents include:
downloaded dependencies
compiler caches
package-manager caches
An artifact is an output produced by a job that should be retained or passed to another job.
Examples include:
compiled binaries
test reports
coverage data
generated documentation
installer packages
A useful distinction is:
Cache accelerates work.
Artifacts preserve the results of work.
Continuous Integration usually focuses on checking whether changes are valid:
compile
test
lint
static analysis
coverage
Continuous Delivery extends that workflow toward producing releasable software:
build
test
package
create release artifact
Continuous Deployment goes further:
commit
│
▼
build
│
▼
test
│
▼
deploy automatically
Not every project requires automatic deployment.
CI/CD should be understood as a set of automation practices rather than a requirement that every repository deploy directly to production.
Kubernetes is a system for orchestrating containerized workloads across one or more machines.
Imagine having dozens or hundreds of containers.
Someone must answer questions such as:
Which machine should run each workload?
What happens when a machine fails?
How are workloads restarted?
How do services discover each other?
How do we scale?
How do we roll out a new version?
Kubernetes automates much of this orchestration.
The official Kubernetes documentation provides a detailed conceptual introduction. (Kubernetes)
A simplified Kubernetes environment looks like:
Kubernetes cluster
│
├── Node A
│ ├── Pod
│ └── Pod
│
├── Node B
│ ├── Pod
│ └── Pod
│
└── Node C
└── Pod
A cluster is the whole Kubernetes environment.
A node is a machine participating in that cluster.
A Pod is Kubernetes's fundamental workload unit and usually contains one primary application container, though it can contain multiple cooperating containers. (Kubernetes)
One of Kubernetes's central ideas is desired state.
Suppose an application should have three instances:
Desired:
instance A
instance B
instance C
If one disappears:
A ✓
B ✗
C ✓
Kubernetes controllers can work to restore the desired state by creating another suitable workload.
Instead of manually managing every process, operators declare what the system should look like and allow Kubernetes to continually reconcile reality with that desired configuration.
GitLab CI/CD asks:
What jobs should run?
A GitLab Runner asks:
Which worker should execute the job?
Kubernetes asks:
Where in this cluster should a containerized workload run?
These systems can therefore be combined.
GitLab Runner includes a Kubernetes executor.
GitLab
│
▼
Runner
│
▼
Kubernetes API
│
▼
Create Pod
│
▼
Run CI job
GitLab states that its Kubernetes executor creates a Kubernetes Pod for each CI job. (GitLab Docs)
The simplified process is:
GitLab creates job
│
▼
Runner accepts job
│
▼
Runner calls Kubernetes API
│
▼
Kubernetes creates Pod
│
▼
Repository/cache/artifacts prepared
│
▼
Job executes
│
▼
Outputs uploaded
│
▼
Pod removed
GitLab divides this process into preparation, pre-build, build, and post-build phases. (GitLab Docs)
Suppose an organization has a very large number of CI jobs.
A single fixed server may become a bottleneck:
runner machine
│
├── job
├── job
└── long queue...
A Kubernetes cluster can distribute workloads:
Kubernetes cluster
│
┌───────────────┼───────────────┐
▼ ▼ ▼
Node A Node B Node C
jobs jobs jobs
Cloud infrastructure may also allow the cluster's underlying capacity to expand and shrink according to demand.
This is especially attractive when an organization already uses Kubernetes and has substantial containerized infrastructure.
For a small workload, introducing Kubernetes may require managing:
cluster nodes
networking
RBAC
service accounts
storage
observability
autoscaling
security
cluster upgrades
runner configuration
That can be far more infrastructure than a simple CI workload requires.
Therefore:
Kubernetes should solve a real infrastructure problem rather than being introduced merely because it is considered modern.
Simple systems are often better systems when they satisfy the requirements.
GitLab provides an official Helm chart for installing GitLab Runner into a Kubernetes cluster.
The resulting architecture is roughly:
Kubernetes cluster
│
▼
GitLab Runner
│
▼
Kubernetes executor
│
▼
one Pod for each CI job
GitLab's official Runner Helm chart configures precisely this pattern. (GitLab Docs)
Helm itself can be thought of as a packaging and templating system for Kubernetes applications.
Both systems unfortunately use the word namespace.
They mean different things.
A GitLab namespace organizes GitLab resources:
company/project
A Kubernetes namespace logically separates Kubernetes resources inside a cluster:
cluster
│
├── namespace: production
├── namespace: staging
└── namespace: ci
So whenever the term appears, ask:
GitLab namespace or Kubernetes namespace?
They are unrelated concepts.
Kubernetes may provide the infrastructure on which CI jobs run:
GitLab
│
▼
Kubernetes executor
│
▼
CI Pod
Or CI may deploy software to Kubernetes:
CI pipeline
│
▼
Build image
│
▼
Push to registry
│
▼
Deploy application
│
▼
Kubernetes cluster
Those are separate architectural choices.
A project can deploy to Kubernetes without using Kubernetes to execute CI.
Likewise, CI can run on Kubernetes even if the final product is not deployed to Kubernetes.
The question:
Docker or Kubernetes?
is often misleading.
Docker and Kubernetes normally operate at different layers.
Docker is concerned with container images and container execution.
Kubernetes orchestrates containerized workloads across infrastructure.
Conceptually:
Application
│
▼
Container image
│
▼
Container runtime
│
▼
Kubernetes orchestration
Docker's documentation provides the container/image perspective, while Kubernetes documentation explains the orchestration layer. (Docker Documentation)
Kubernetes is not the only way to scale CI infrastructure.
GitLab also provides autoscaling runner technologies capable of dynamically creating compute instances when jobs arrive.
The general architecture is:
few jobs
│
▼
few workers
many jobs
│
▼
create more workers
demand falls
│
▼
remove excess workers
The lesson is important:
"We need autoscaling" does not automatically mean "we need Kubernetes."
An organization may have several types of runners:
Linux
Windows
macOS
ARM
GPU
special hardware
Runner tags allow jobs to request compatible infrastructure.
Conceptually:
windows-build:
tags:
- windowsGitLab can then match the job with an eligible runner.
This makes mixed CI environments possible:
GitLab
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Linux Windows macOS
GCC MSVC AppleClang
A serious cross-platform project therefore does not need to force every job onto one runner type.
GitLab-hosted and self-managed runners can coexist.
For example:
GitLab
│
├── hosted Linux runner
│ └── normal builds
│
├── hosted Windows runner
│ └── Windows testing
│
└── self-managed runner
└── hardware-in-the-loop tests
This allows infrastructure to be chosen according to the requirements of each job.
CI jobs execute commands.
For example:
script:
- ./build.shThat script may potentially access:
files
network resources
environment variables
tokens
credentials
other services
Runner security is therefore extremely important.
Useful questions include:
Who can modify .gitlab-ci.yml?
Which secrets does the job receive?
Can untrusted contributors execute jobs?
Is the job isolated?
Does it have privileged access?
Can the container reach the host?
CI infrastructure should follow the principle of least privilege:
Give each job only the capabilities it actually requires.
CI architecture involves several competing goals.
You want:
reproducibility
isolation
speed
low cost
maintainability
But improvements in one area can sometimes make another harder.
For example:
fresh disposable environments
→ excellent isolation
persistent machine state
→ potentially faster reuse
Modern CI often combines ephemeral execution environments with explicit caching so that jobs remain isolated while expensive downloads and compilation work can still be reused safely.
A beginner does not need to master Kubernetes immediately.
A more useful progression is:
Git
↓
GitLab repository
↓
.gitlab-ci.yml
↓
pipeline
↓
stage
↓
job
↓
runner
↓
executor
↓
Docker/container image
↓
cache and artifacts
↓
deployment
↓
self-managed runners
↓
autoscaling
↓
Kubernetes
Each concept builds naturally on the previous one.
All the concepts can now be assembled into one flow:
Developer
│
│ git push
▼
GitLab repository
│
▼
.gitlab-ci.yml
│
▼
Pipeline
│
├── Job A
├── Job B
└── Job C
│
▼
Runner selection
│
▼
Executor
│
┌────┼──────────────┐
│ │ │
Docker Shell Kubernetes
│ │ │
▼ ▼ ▼
container host Pod
│ │ │
└────┴──────┬───────┘
▼
commands execute
│
▼
cache / artifacts
│
▼
GitLab result
│
▼
optional release/deployment
Different layers answer different questions.
GitLab: What should happen?
Pipeline: What workflow should execute?
Job: What individual work must be done?
Runner: Which worker accepts the job?
Executor: How does the runner execute it?
Container image: What software environment does the job receive?
Artifacts: What outputs should survive?
Kubernetes: How can containerized workloads be scheduled across a cluster?
Subscription: Which GitLab product features and allowances are available?
Compute quota: How much metered runner capacity can be consumed?
Namespace: Which organizational container owns the projects and associated resources?
Once these responsibilities are separated, GitLab CI/CD becomes much easier to reason about.
The following official documentation is a useful companion to this article. The order below is also a reasonable reading order for a beginner.
| Topic | Official documentation | Why read it |
|---|---|---|
| GitLab Runner basics | GitLab Docs — GitLab-hosted runners (GitLab Docs) | Explains GitLab-provided runners, hosted execution, isolation, and supported environments. |
| Runner scope | GitLab Docs — Manage runners (GitLab Docs) | Explains instance, group, and project runners. |
| Compute usage | GitLab Docs — Compute minutes (GitLab Docs) | Explains job-duration calculation, cost factors, top-level namespace accounting, and parallel-job consumption. |
| Monthly quota | GitLab Docs — Compute usage for instance runners (GitLab Docs) | Explains quota enforcement and monthly reset behavior. |
| Additional compute | GitLab Docs — Purchase additional compute minutes (GitLab Docs) | Explains purchased compute and how it relates to the included quota. |
| Namespaces | GitLab Docs — Namespaces (GitLab Docs) | Explains user, group, and subgroup namespaces. |
| Groups | GitLab Docs — Groups (GitLab Docs) | Useful for understanding organizational hierarchy. |
| GitLab offerings and plans | GitLab Docs — GitLab plans (GitLab Docs) | Explains GitLab.com, Self-Managed, Dedicated, and subscription tiers. |
| Subscription behavior | GitLab Docs — Manage subscription (GitLab Docs) | Explains how GitLab.com subscriptions apply to top-level groups. |
| Current pricing and quotas | GitLab — Pricing (GitLab) | Current Free, Premium, and Ultimate feature and compute comparisons. |
| Free user limits | GitLab Docs — Free tier user and group limits (GitLab Docs) | Explains current Free-tier group membership restrictions. |
| Storage limits | GitLab Docs — Storage (GitLab Docs) | Explains repository and LFS quotas. |
| Kubernetes executor | GitLab Docs — Kubernetes executor (GitLab Docs) | Explains how GitLab creates one Kubernetes Pod per CI job. |
| GitLab Runner on Kubernetes | GitLab Docs — GitLab Runner Helm chart (GitLab Docs) | Explains installing and operating GitLab Runner inside Kubernetes. |
| Docker fundamentals | Docker Docs — What is Docker? (Docker Documentation) | Explains images, containers, registries, Docker Engine, client, and daemon. |
| Container fundamentals | Docker Docs — What is a container? (Docker Documentation) | Beginner explanation of container isolation and containers versus VMs. |
| Docker learning path | Docker Docs — Get started (Docker Documentation) | Hands-on introduction to Docker fundamentals. |
| Docker technical reference | Docker Docs — Reference documentation (Docker Documentation) | Reference for Dockerfile, CLI, APIs, Compose, and Docker Engine. |
| Kubernetes fundamentals | Kubernetes Docs — Concepts Overview (Kubernetes) | Main entry point for understanding Kubernetes architecture and concepts. |
| Pods | Kubernetes Docs — Pods (Kubernetes) | Explains Kubernetes's fundamental workload unit. |
| Nodes | Kubernetes Docs — Nodes (Kubernetes) | Explains the machines that make up a Kubernetes cluster. |
Start with GitLab-hosted runners, then read Namespaces, Compute minutes, and GitLab plans. At that point, the terms that appear throughout the GitLab UI and documentation should make much more sense.
Next, study Docker through What is Docker? and What is a container?. Once images and containers are comfortable concepts, return to GitLab and study the different executor models.
Only after those foundations are clear is it worth studying the Kubernetes material. Begin with the Kubernetes Concepts Overview, then Nodes and Pods, and finally return to GitLab's Kubernetes executor documentation.
That sequence creates this conceptual progression:
GitLab
↓
Pipeline
↓
Runner
↓
Executor
↓
Container
↓
Docker
↓
Cluster
↓
Node
↓
Pod
↓
Kubernetes executor
This is much easier than attempting to learn GitLab, Docker, and Kubernetes simultaneously.
Product limits are not permanent technical constants.
Values such as:
compute minutes
subscription prices
runner sizes
storage quotas
user limits
feature availability
can change independently of the fundamental CI/CD concepts described in this article.
The commercial figures mentioned here were checked against GitLab's published documentation and pricing information in August 2026. For future purchasing or architectural decisions, the linked official documentation should be treated as authoritative rather than the numerical examples in this article.
The underlying conceptual model is much more stable:
GitLab orchestrates
Runner executes
Executor defines how
Image defines the environment
Artifacts preserve outputs
Namespace organizes ownership
Compute quota meters managed capacity
Kubernetes orchestrates workloads at scale
Those concepts provide the foundation needed to understand more advanced GitLab CI/CD architectures.
