GitLab Runners Setup

A GitLab Runner is the agent that actually executes your CI/CD pipeline jobs. When GitLab triggers a pipeline, it sends each job to an available runner, which runs the commands and reports the result back.

What a Runner Is — The Delivery Driver Analogy

  GitLab (the restaurant)       Runner (the delivery driver)
  ───────────────────────       ─────────────────────────────
  Prepares the order            Picks up the order
  (reads .gitlab-ci.yml)        (receives the job)
  Sends it out                  Executes the commands
                                Returns the result ✅ or ❌

Without a runner, your pipeline jobs queue up and never execute.

Shared Runners vs Specific Runners

TypeWho Manages ItAvailable ToBest For
Shared RunnerGitLab.com (free)All projects on GitLab.comQuick start, small projects
Group RunnerYour teamAll projects in one groupShared team infrastructure
Project RunnerYour teamOne specific project onlyIsolated, sensitive workloads

GitLab.com Shared Runners — Free Tier

Every account on GitLab.com gets 400 free CI/CD minutes per month on shared runners. These runners run on Linux, Windows, and macOS virtual machines managed by GitLab. No setup required — your pipeline runs as soon as you push a .gitlab-ci.yml file.

  Free tier: 400 minutes/month
  ────────────────────────────────────────────────
  Pipeline #1:  12 minutes  → 388 remaining
  Pipeline #2:   8 minutes  → 380 remaining
  Pipeline #3:  15 minutes  → 365 remaining
  ...
  Pipeline runs until minutes reach 0 for the month

Runner Executors — How Jobs Actually Run

An executor is the method a runner uses to run each job. The most common options are:

ExecutorHow It WorksBest For
ShellRuns commands directly on the server's shellSimple setups, single-purpose servers
DockerSpins up a fresh Docker container per jobIsolated, reproducible builds
KubernetesCreates a Kubernetes pod per jobLarge-scale, cloud-native teams
VirtualBoxCreates a fresh VM per jobOS-level isolation needs

The Docker executor is the most popular choice because each job gets a clean, isolated environment defined by the image keyword in your YAML file.

Installing a Self-Hosted Runner on Linux

Use a self-hosted runner when you need more minutes, faster hardware, access to private networks, or special software not available on shared runners.

Step 1 — Download and Install

  # Download the runner binary
  curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash

  # Install it
  sudo apt-get install gitlab-runner

Step 2 — Register the Runner

Registration links the runner to your GitLab project or group. Get the registration token from Settings → CI/CD → Runners → New project runner.

  sudo gitlab-runner register

  Prompts you to enter:
  ─────────────────────────────────────────────────
  GitLab URL:      https://gitlab.com
  Registration token:  glrt-xxxxxxxxxxxx
  Description:     my-linux-runner
  Tags:            linux, docker, production
  Executor:        docker
  Default image:   alpine:latest
  ─────────────────────────────────────────────────
  Runner registered successfully ✅

Step 3 — Start the Runner

  sudo gitlab-runner start

The runner appears in Settings → CI/CD → Runners as a green dot (online) within a few seconds.

Runner Tags — Routing Jobs to the Right Runner

Tags let you direct specific jobs to specific runners. When you register a runner, you give it tags. In your YAML, a job with matching tags runs only on tagged runners.

  Runners available:
  ─────────────────────────────────────────────
  Runner A:  tags = [linux, docker]
  Runner B:  tags = [windows, shell]
  Runner C:  tags = [macos, xcode]

  .gitlab-ci.yml job:
  build-ios-app:
    stage: build
    tags:
      - macos
      - xcode          ← only runs on Runner C
    script:
      - xcodebuild -scheme MyApp

  run-tests:
    stage: test
    tags:
      - linux          ← only runs on Runner A
    script:
      - npm test

Runner Status and Management

View all runners for a project at Settings → CI/CD → Runners. Each runner shows:

  • Status (online, offline, or paused)
  • Last contact time
  • Tags assigned
  • Total jobs run
  Runners for project: my-webapp
  ────────────────────────────────────────────────────
  🟢 my-linux-runner   online     linux, docker   847 jobs
  🔴 old-mac-runner    offline    macos           12 jobs
  ⏸️  staging-runner   paused     docker          230 jobs
  ────────────────────────────────────────────────────

Pausing and Removing a Runner

Pause a runner when you need to take it offline temporarily for maintenance. No new jobs are sent to a paused runner, but running jobs finish. Delete a runner from the three-dot menu next to it in the runners list.

Runner Configuration File

After registration, the runner stores its settings in /etc/gitlab-runner/config.toml. You can edit this file to tune concurrency (how many jobs it runs at once) and other settings.

  /etc/gitlab-runner/config.toml
  ──────────────────────────────────────────
  concurrent = 4          ← run up to 4 jobs at the same time

  [[runners]]
    name = "my-linux-runner"
    url = "https://gitlab.com"
    executor = "docker"
    [runners.docker]
      image = "alpine:latest"
      privileged = false

Security Best Practices for Runners

  • Never run a shared runner with privileged = true — it gives containers full access to the host machine
  • Use project-specific runners for jobs that handle secrets or production credentials
  • Restrict which projects can use a runner by going to the runner's settings and disabling "Allow projects to add to this runner"
  • Keep the runner binary updated — GitLab releases security patches regularly

Checking Runner Logs

If a runner behaves unexpectedly, check its service logs:

  sudo gitlab-runner --debug run     ← run in foreground with verbose output
  sudo journalctl -u gitlab-runner   ← view system logs on Linux

Leave a Comment

Your email address will not be published. Required fields are marked *