Getting to know the three GitLab Runner classifications — shared, group, and specific — along with the shell, docker, and kubernetes executor types. Then registering your own runner with gitlab-runner register and routing jobs to specific runners using tags.

In episode 2 you successfully created your first .gitlab-ci.yml and got a pipeline running. But have you ever asked: who actually runs that job? The answer is the GitLab Runner — the unsung hero that picks jobs up from the queue and executes them. This episode dissects runner type classifications, executor types, how to register, and how tags route jobs to the right runner.
This understanding is crucial: in large companies, the runner architecture determines the speed, cost, and security of the entire pipeline. Decisions like "run on a shared runner or a dedicated runner?" and "use a Docker executor or a Kubernetes executor?" are architectural decisions, not just configuration.
Runners can be distinguished by the scope of their service:
| Type | Scope | When to Use |
|---|---|---|
| Shared | Entire instance | Learning, lightweight pipelines, getting started fast |
| Group | One group/org | Standardizing across all team projects |
| Specific | One project | Special needs or security |
Here's a simple analogy: a shared runner is like public shuttle service, a group runner is like an office shuttle bus serving all divisions, and a specific runner is like a private car serving one office — with specs that can be customized.
The executor determines how the runner executes jobs. The three most popular:
image keyword). This is the standard for production pipelines.| Executor | Isolation | Best for |
|---|---|---|
| Shell | None | Simple machines, host access |
| Docker | Container | Production standard |
| Kubernetes | Dynamic pod | Elastic scaling in a K8s cluster |
By analogy: the shell executor is like cooking directly in the shared kitchen, the docker executor is like cooking in your own clean, portable pot, while the kubernetes executor is like ordering a brand-new chef for every order.
Runners run on machines you control — a laptop, VM, or CI server. Installation on Ubuntu/Debian uses GitLab's official repository:
curl -sS https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get update
sudo apt-get install -y gitlab-runner
gitlab-runner --versionThe runner is registered as a system service (gitlab-runner), and all configuration is stored in /etc/gitlab-runner/config.toml.
Every runner must be registered to GitLab with a unique token. The token is taken from Settings → CI/CD → Runners in the project, group, or instance — depending on the runner type you want to create. Example non-interactive registration:
gitlab-runner register \
--url https://gitlab.com/ \
--token glrt-XXXXXXXXXXXX \
--executor docker \
--description "docker-runner-01" \
--docker-image alpine:3.20The most important parameters:
--url — your GitLab instance address (https://gitlab.com/ for SaaS).--token — the registration token from the Runners page.--executor — the executor type used (docker, shell, kubernetes, etc.).--docker-image — the default image for jobs that don't write their own image keyword.The registration result is stored in /etc/gitlab-runner/config.toml — here's the condensed version:
concurrent = 4
[[runners]]
name = "docker-runner-01"
url = "https://gitlab.com/"
executor = "docker"
[runners.docker]
image = "alpine:3.20"
privileged = falseWarning
Never enable privileged = true without a strong reason. This mode gives containers full root access to the host — if a job runs untrusted code, this can be dangerous. The difference between Docker-in-Docker (which needs privileged) vs Kaniko (which doesn't) will be covered in episode 6.
Once a runner is registered, you can give it tags — labels that jobs use to choose which runner handles their work. Register with --tag-list:
gitlab-runner register \
--url https://gitlab.com/ \
--executor docker \
--tag-list "docker,high-cpu"Inside .gitlab-ci.yml, jobs use the tags keyword to request a runner with those labels:
deploy_prod:
stage: deploy
script:
- ./deploy.sh
tags:
- docker
- high-cpuThe deploy_prod job will only be picked up by a runner that has all of those tags. If no runner matches, the job will sit idle (stuck) forever. Rule of thumb: use tags for truly specific routing — like architecture (amd64), hardware (gpu), or job type (build, deploy) — not as a substitute for executor configuration.
To make sure your runner is healthy and registered, use these commands:
gitlab-runner status
gitlab-runner list
glab runner list--run-untagged=true.In this episode 3, you've mastered the infrastructure side of GitLab CI/CD:
gitlab-runner register plus --url, --token, --executor, and --docker-image.tags keyword, plus verification with gitlab-runner status, gitlab-runner list, and glab runner list.Your pipeline now has a clear workforce. In episode 4 we'll control when that work runs — dynamic control flow with rules and workflow: the legacy only/except vs modern rules, if, changes, exists conditions, the when parameter, and preventing duplicate pipelines with workflow: rules. See you in episode 4!