6. GitLab Runners & Executors

When you trigger a pipeline in GitLab, where does the code actually compile? Who executes the commands listed inside .gitlab-ci.yml? That work is handled by the GitLab Runner—an open-source application written in Go that acts as an execution agent.

Runner Hierarchy: Shared vs. Specific

GitLab registers and segments runners into three access tiers:

  1. Shared Runners: Available to every project across the entire GitLab instance. For GitLab.com SaaS, GitLab provides shared runners with free build minutes.
  2. Group Runners: Assigned to a parent group. Every subgroup and project inside that group inherits these runners automatically.
  3. Specific (Project) Runners: Tied strictly to a single project. Ideal for specialized builds, unique hardware requirements, or accessing secure databases on local environments.

Understanding Executors

When you register a runner, you must select an Executor. The executor determines the environment in which your script commands are executed:

ExecutorHow it worksPros / Cons
ShellRuns scripts directly on the host machine where the runner is installed.Fast and easy, but has no isolation. A script can delete local host files or corrupt the server.
DockerSpins up a clean Docker container for each job and tears it down afterwards.Superb isolation. Completely reproducible environments. (Highly Recommended)
KubernetesSpins up individual Pods inside a Kubernetes cluster for each pipeline job.Extremely scalable, perfect for cloud elastic resource scheduling. Requires K8s setup.

How to Install & Register a Custom GitLab Runner

If you want to host your own runner on an Ubuntu Linux server to run jobs for free without SaaS minute limits, here is the setup guide:

Step 1: Download the Binary

# Download the binary for your system architecture
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/v15.0.0/binaries/gitlab-runner-linux-amd64

# Give it execution permissions
sudo chmod +x /usr/local/bin/gitlab-runner

# Create a system user to run the service
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

# Install and start as a system service
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start

Step 2: Register with GitLab

Go to your GitLab project's sidebar and navigate to Settings > CI/CD > Runners. Expand the panel, copy the registration token and instance URL, then run:

sudo gitlab-runner register

The CLI will prompt you to enter configuration details:

  1. Enter your GitLab instance URL (e.g., `https://gitlab.com/`).
  2. Enter the registration token.
  3. Enter a description for the runner (e.g., `staging-docker-runner`).
  4. Enter runner tags separated by commas (e.g., `docker,nodejs`). Tags help jobs target this runner!
  5. Select the executor type (e.g., `docker`).
  6. If Docker is chosen, define the default image (e.g., `alpine:latest`).

Using Tags in Pipelines

You can direct specific jobs to run strictly on specialized runners using the tags: attribute in your job configuration:

compile_ios_app:
  stage: build
  script:
    - xcodebuild -workspace MyApp.xcworkspace
  tags:
    - macos-runner-mac-studio  # Directs job to a runner hosted on physical macOS hardware
Security Warning: Never run untrusted code on a Shell executor! A malicious script could easily steal the runner machine's environment variables, read ssh keys, or execute root shell commands. Always default to the Docker executor.