GitLab Runner Handbook [2026 Edition]
GitLab Runner is one of those tools that sits at the heart of GitLab CI/CD. It picks up the jobs you define in your pipeline and runs them, reporting results back to GitLab when done.
You can set it up as a shared runner that anyone in your organization can use, or register dedicated runners for specific projects. It works on your own hardware, in Docker, or on Kubernetes.
What is GitLab Runner?
It’s open source, so you can download the binary and run it pretty much anywhere. Once registered with your GitLab instance, it handles the grunt work of your CI/CD pipeline: checking out code, installing dependencies, running tests, and reporting back.
The main appeal is keeping your CI/CD self-hosted while still being able to scale. You control the infrastructure, and GitLab handles the coordination.
Is GitLab Runner part of GitLab?
Yes, but it’s deployed separately. GitLab ships it as a single binary that you install on a machine. You can also run it in a Docker container or deploy it to Kubernetes.
One thing I like about Runner is that you can register multiple runners to the same GitLab instance. You might have a small fast runner for quick jobs and a larger one for resource-intensive test suites. You tag runners to control which jobs run where.
How does the GitLab Runner work?
Runner reads your .gitlab-ci.yml and picks up jobs from the queue. For each job, it:
- Checks out the code
- Installs dependencies
- Runs your scripts
- Reports the result back to GitLab
You can configure Runner to run jobs on specific platforms. Maybe you need some jobs to run on Linux and others on macOS - Runner handles that through tags and executor configuration.
Runner registration in 2026 (glrt- tokens)
GitLab 17.0 (May 2024) deprecated the old registration token method. You now create runners directly in the GitLab UI (project or group Settings > CI/CD > Runners > New runner) and receive an authentication token starting with glrt-. The registration command changed:
# New registration flow (GitLab 17.0+)
gitlab-runner register \
--url https://gitlab.example.com \
--token glrt-YOUR_RUNNER_TOKEN \
--executor docker \
--docker-image alpine:latest \
--name my-runner
The old --registration-token flag is deprecated. If you’re running GitLab < 17.0 and see docs using --registration-token, those instructions still work but you should plan to migrate. The old method was removed in GitLab 18.0.
5 Advantages of GitLab Runner:
- Easy to install
- Open source
- Scales with your needs
- Supports job tagging for routing
- Works as shared or dedicated
That’s the short version. It does what you need without much fuss.
What are the Best Practices?
Here’s what I recommend based on running these in production:
Keep it updated. New versions come out regularly with bug fixes and features. Set a reminder to check every few months.
Use tags. Tag your jobs and runners so the right work goes to the right place. For example, you might have docker jobs go to runners with Docker installed.
Run multiple instances. Don’t rely on a single runner. If it goes down, your pipelines stop. Two to three runners minimum for anything serious.
Lock down security. When you register a runner, you get a token. Treat it like a password. Runner also supports TLS and you can run jobs in isolated environments.
Watch the logs. Runner will tell you when things go wrong. Make sure you’re actually reading them.
Use caching. If your builds download the same dependencies every time, caching saves a lot of time. It’s built in and worth configuring.
Leverage what GitLab CI/CD offers. Runner integrates deeply with GitLab. Get familiar with the CI/CD features before reinventing wheels.
Is Docker required?
No. You can install the binary directly on a Linux machine, macOS, or Windows. Docker is convenient and popular, but optional.
The same goes for Kubernetes. It’s great for scaling, but you don’t need it. Many teams run Runner directly on VMs and that works fine.
GitLab vs Jenkins?
I’ve used both. The main difference is scope. Jenkins is a general-purpose automation server that can do almost anything. Runner is purpose-built for GitLab CI/CD.
If you’re already using GitLab, Runner fits naturally. You don’t configure webhooks or external systems - it just works with your existing GitLab setup.
Jenkins gives you more flexibility if you need to automate things beyond CI/CD. Runner is simpler for its specific use case.
How can you check the version?
gitlab-runner version
That’s it.
How much RAM do I need for GitLab runner?
It depends on what you’re running. A single job might use 100-500MB of RAM depending on the workload. For planning purposes, I usually suggest:
- Minimum: 1GB RAM for light workloads
- 2-4GB for moderate CI/CD activity
- More if you’re running parallel jobs or memory-intensive builds
The actual number varies based on your executor type, job complexity, and how many jobs run concurrently. Start small and scale up if you see issues.
Is there a way to use GitLab without GitLab Runner?
GitLab CI/CD requires a runner. Without one, your pipelines won’t execute. The jobs just sit in the queue forever.
You can use GitLab for source control, issue tracking, and code review without Runner, but for CI/CD you need it.
The Fleeting executor — replacing Docker Machine
Docker Machine executor was deprecated in GitLab 15.x and removed in 17.0. The replacement is the Fleeting executor with the gitlab-runner-autoscaler plugin.
Fleeting provides auto-scaling runners on cloud infrastructure. The AWS plugin spins EC2 instances on demand, runs a job, and terminates them. Setup overview:
# /etc/gitlab-runner/config.toml
[[runners]]
name = "fleeting-aws-runner"
url = "https://gitlab.example.com"
token = "glrt-YOUR_TOKEN"
executor = "instance"
[runners.autoscaler]
plugin = "fleeting-plugin-aws"
[runners.autoscaler.plugin_config]
name = "my-fleeting-asg"
profile = "default"
config_file = "/root/.aws/config"
credentials_file = "/root/.aws/credentials"
[runners.autoscaler.connector_config]
username = "ec2-user"
use_external_addr = true
[runners.autoscaler.policy]
idle_count = 1
idle_time = "5m0s"
max_use_count = 100
max_instances = 10
The Fleeting executor also supports GCP and Azure through separate plugins. The AWS plugin is the most mature.
Can I deploy the Runner on AWS?
Yes. AWS has an official AMI that makes this straightforward. You can also run it as a container on ECS or EKS if you prefer Kubernetes-style deployments.
For auto-scaling, the Fleeting executor is now the recommended approach — it replaced Docker Machine in GitLab 17.0. See the section above for configuration details. For Fargate-based setups, see Autoscaling GitLab CI on AWS Fargate.
How many Runners can I attach on GitLab?
As many as you want. GitLab doesn’t impose a hard limit on registered runners.
The constraint is how many concurrent jobs each runner handles. Modern GitLab allows 100-500 concurrent jobs per runner depending on configuration and resources. You scale by adding more runners or increasing concurrency.
Can I use the Runner locally?
Yes. Install it on your laptop or a local server, register it with your GitLab instance, and you’re good to go. Useful for testing pipelines before pushing.
Installation docs are on gitlab.com. The command-line interface handles everything once installed.
Which features are available?
Runner comes with a solid set of features:
- Multi-language support (whatever you can run in a shell)
- Docker and Kubernetes integration
- Parallel job execution
- Caching for dependencies
- Pre and post-job scripts
- Custom environment variables
- Job concurrency control
Most CI/CD needs are covered out of the box.
Are there any security measures for GitLab Runner?
Yes. Runner provides:
- Job isolation (each job runs in its own environment)
- Encrypted secrets (stored securely, not in logs)
- Network isolation options
- Runner authentication
For sensitive workloads, you can run jobs in isolated VMs or private networks. Runner also supports using private Docker images from container registries.
Are there any other considerations?
A few practical things:
Resources. Give Runner enough RAM and CPU. Starving it causes jobs to fail or run slowly. 1GB RAM minimum, more if you’re running concurrent jobs.
Storage. Jobs generate logs and artifacts. Make sure you have disk space, especially if you keep build artifacts around.
Updates. Keep Runner updated. Old versions sometimes have issues with newer GitLab features.
Monitoring. Check that jobs are actually completing. Runner has status commands you can script.
Can I install it on macOS?
Yes. The binary works on macOS. Install it with Homebrew or download directly:
brew install gitlab-runner
gitlab-runner install
gitlab-runner start
From there you register it with your GitLab instance and you’re set.
Can I install it on Windows?
Yes. GitLab provides Windows binaries. The process is similar to other platforms - download, install, register.
How to resolve the x509 certificate signed by unknown authority
If you see this error, Runner can’t verify GitLab’s certificate. Options:
- Add GitLab’s CA certificate to your system trust store
- Configure Runner to skip certificate verification (less secure, not recommended for production)
- Use Let’s Encrypt certificates that are already trusted by most systems
Check Runner’s docs for the exact configuration. This usually bites you when running a self-signed GitLab instance.
Are there any limitations?
A few to be aware of:
Concurrent jobs per runner. The default limit is around 20, but you can configure this higher based on your resources. Some setups run 100-500 concurrent jobs on a single runner.
Job timeout. Maximum job duration is 24 hours by default. You can adjust this.
Session length. Interactive sessions (for debugging) have their own timeout settings.
These limits are reasonable for most use cases. If you hit them, you’re probably at a scale where you’d customize anyway.
Are there any other tips?
Three things I’d add:
Read the official docs. They’re well-maintained and cover edge cases.
Use the command line. Runner’s CLI is straightforward and gives you full control.
Start simple. Don’t overcomplicate your setup early. Add complexity only when you need it.
What to do when the GitLab Runner is not picking up Jobs?
First, check the obvious:
- Is Runner running? (
gitlab-runner status) - Does it show as active in GitLab’s UI?
- Are there system resources free? (RAM, disk, CPU)
If Runner is running but idle, the problem might be:
- Token mismatch (re-register if needed)
- Tags mismatch (job requires tags the runner doesn’t have)
- Network issues (Runner can’t reach GitLab)
- No available concurrent slots (all busy with other jobs)
Check the logs too: gitlab-runner log
Also verify the job’s tags match your runner’s tags. This catches people regularly.
How does GitLab Runner work with Kubernetes?
You can run Runner inside Kubernetes. It integrates with the Kubernetes API to spawn pods for each job. Benefits:
- Each job gets a fresh pod
- Auto-scaling based on job queue
- Resource isolation per job
- Good fit for cloud-native workflows
The Helm chart makes this relatively easy to set up. You can also use it with Helm for managing applications in the same cluster.
How to check if GitLab Runner is running?
gitlab-runner verify
This checks connectivity and reports the runner’s status.
Other useful commands:
gitlab-runner status # Is it running?
gitlab-runner show # Current configuration
gitlab-runner list # All registered runners
How to check Logs?
gitlab-runner log
This shows recent log entries. For system-level logs:
gitlab-runner log system
If a job fails, check both Runner logs and the job’s individual log in GitLab’s UI.
Conclusion
GitLab Runner is straightforward and reliable. It handles CI/CD jobs without much overhead, runs on various platforms, and scales when needed.
You get the automation of CI/CD with control over where it runs. For teams using GitLab, it’s a natural choice that works well out of the box.
Comments