UNC Campus Git: Gitlab Runner

Summary

This article describes how to install and configure Gitlab Runners.

Body

This article describes how to install and configure Gitlab Runners.

 

In This Article:

 

Before You Begin

Before creating a runner verify if there are any exiting runners via the GitLab UI.

  • Navigate to your project in GitLab.
  • From the left hand menu, go to Settings > CI/CD.
  • Expand the Runners section.
  • If the project has ‘Assigned project runners’, verify that they are not paused. If one is paused, you can resume accepting jobs by clicking the Triangle button to its right.
  • If the project has NO ‘Assigned project runners’, but you see a group runner listed, then the group runner gets automatically assigned to the project when you run a pipeline. This should be fine as long as all the projects share the same runner environment and there are no delays due to queuing or resource contention. But in other cases, it is preferable to create a new runner.

 

Instructions

 

Step 1: Create and Register a Project Runner

  • Navigate to your project in GitLab.
  • From the left hand menu, go to Settings > CI/CD.
  • Expand the Runners section.
  • Click New project runner.
  • To run tagged jobs (optional), in the Tags field, enter the job tags separated with a comma.
    • For example, macos, ruby.
  • To run untagged jobs, select the Run untagged jobs checkbox.
  • In the Maximum job timeout field, enter a value in seconds. The minimum value is 600 seconds (10 minutes). If not defined, the job timeout for the project is used instead.
  • Restrict the runner to specific projects.

 

  • Once you create runner, it should give you a page to register the runner.

  • On the machine where the runner is installed and registered (as per Step 2), check /etc/gitlab-runner/config.toml or ~/.gitlab-runner/config.toml and look for the token field under [[runners]] 

 

Step 2: Install the runner and register

  • Select your OS (Linux/macOS/Windows). This will generate a registration token and url.
  • If you click on 'How do I install GitLab Runner', it will provide the command line instructions. Additionally you can refer to GitLab documentation to install runners
  • Register the runner with GitLab (NOTE: the below commands might slightly differ based on the OS of the runner)
sudo gitlab-runner register
       # You'll be prompted for:
        # - GitLab instance URL  
        # - Registration token (from the UI)
        # - Runner description 
        # - Tags (comma-separated, optional)
        # - Executor (enter "shell" for direct execution)
        # After registration, start the runner
sudo gitlab-runner run

 

  • After registration, the runner configuration is stored in /etc/gitlab-runner/config.toml (Linux)  or ~/.gitlab-runner/config.toml (macOS). 
  • If you're using the GitLab Runner Operator or Helm chart, the token is stored in a Kubernetes secret. Look for secrets containing runner-token in your namespace.
  • Some installations pass the token via environment variables like RUNNER_TOKEN

 

Step 3: Create a Project Pipeline

  • Create a .gitlab-ci.yml file in root level of your project repository. You can edit the file using Pipeline Editor
  • Below is a sample code, but you can refer to this yaml reference 
# This file is a template, and might need editing before it works on your project.
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/#stages
#
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/development/cicd/templates/
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
stages:          # List of stages for jobs, and their order of execution
  - build
  - test
  - deploy
build-job:       # This job runs in the build stage, which runs first.
  stage: build
  script:
    - echo "Compiling the code..."
    - echo "Compile complete."
unit-test-job:   # This job runs in the test stage.
  stage: test    # It only starts when the job in the build stage completes successfully.
  script:
    - echo "Running unit tests... This will take about 60 seconds."
    - sleep 60
    - echo "Code coverage is 90%"
lint-test-job:   # This job also runs in the test stage.
  stage: test    # It can run at the same time as unit-test-job (in parallel).
  script:
    - echo "Linting code... This will take about 10 seconds."
    - sleep 10
    - echo "No lint issues found."
deploy-job:      # This job runs in the deploy stage.
  stage: deploy  # It only runs when *both* jobs in the test stage complete successfully.
  environment: production
  script:
    - echo "Deploying application..."
    - echo "Application successfully deployed."

 

Step 4: Job Execution Flow

When your runner picks up a job, GitLab follows this execution flow :

  Source Preparation
      Exports variables to shell context
       Executes git fetch with depth=20 (optimized for CI)
       Updates submodules if configured
   Cache Download
       Downloads cached files from previous runs
   Artifact Download
       Downloads artifacts from dependent jobs
   Main Job Execution
       Runs before_script commands
       Executes main script commands
       All scripts run with set -eo pipefail (fails early on errors)
   After Script (Always runs, even on failure)
       Executes cleanup or notification commands
   Cache Upload
       Uploads specified paths to cache
   Artifact Upload
       Saves job artifacts for dependent jobs

 

Step 5: Trigger a Pipeline

There are several ways to run the jobs defined in your .gitlab-ci.yml file. They range from fully automated triggers based on code changes to manual initiation and external API calls. The method you choose determines the value of the CI_PIPELINE_SOURCE predefined variable, which you can use in your rules to control which jobs run.

Trigger Type CI_PIPELINE_SOURCE value Procedure Usage
Code Push push The push creates a pipeline, and a runner executes the jobs. Running tests, linters, and builds on every commit to get immediate feedback.
Merge Request merge_request_event The MR event creates a pipeline, and a runner executes the jobs. Pre-merge validation, such as running a full test suite or checking code coverage only when an MR is opened.
scheduled  schedule The schedule creates a pipeline at a specific time, and a runner executes the jobs. Regular tasks like cleaning up temporary data, running dependency vulnerability scans, or executing long-running performance tests.
Manual (via UI) web A user clicks "Run pipeline", creating a pipeline, and a runner executes the jobs. Deployments to production that require a human to approve and initiate the process, or running a pipeline for a specific branch without making a code change.
API Trigger (with Trigger Token) trigger The API call creates a pipeline, and a runner executes the jobs. Integrating GitLab with external automation tools, allowing one microservice's pipeline to trigger another's.
Webhook webhook The external event creates a pipeline, and a runner executes the jobs. Triggering pipelines based on non-code events, like running a cleanup job when an issue is closed.
Multi-project Pipeline pipeline For multi-project pipelines created with CI_JOB_TOKEN or the trigger keyword.  
  • All trigger types are automatically set in CI_PIPELINE_SOURCE.
  • You never need to define this variable in your .gitlab-ci.yml.
  • You only reference it in rules: or only/except to control job execution.

Examples

  • To run a job only for scheduled pipelines
nightly_cleanup:
  script: echo "Running nightly cleanup..."
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"  # This uses the variable, doesn't define it

 

  • To skip certain jobs for merge request pipelines
deploy_to_prod:
  script: echo "Deploying..."
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never  # Don't run in MRs
    - when: manual  # Run manually for other pipeline types

 

  • To trigger a pipeline manually
    • Go to your project in GitLab.
    • Navigate to Build > Pipelines.
    • Click Run pipeline.
    • Select the branch and click Run pipeline.

Your runner should now pick up and execute the job. The output will look similar to:

Running with gitlab-runner 18.x.x 
        on project-runner-18.9.1 TOKEN, system ID: SYSTEM_ID
        Preparing the "shell" executor
        Using Shell (bash) executor...
        Preparing environment
        Running on HOSTNAME...
        Getting source from Git repository
        Fetching changes with git depth set to 20...
        Checking out HEAD as detached...
        Executing "step_script" stage of the job script
        $ echo "Building the project for GitLab 18.9.1"
        Building the project
        Job succeeded

 

 

Tips and Troubleshooting

Handling Timeouts

Defining Timeout Limits

You can define how long a job can run before it times out.

  • In the top bar, select Search or go to and find your project.
  • Select Settings > CI/CD.
  • Expand General pipelines.
  • In the Timeout field, enter the number of minutes, or a human-readable value like 2 hours.

 

Understanding Maximum Job Timeout

  • Example 1 - Runner timeout bigger than project timeout
    • You set the maximum_timeout parameter for a runner to 24 hours.
    • You set the Maximum job timeout for a project to 2 hours.
    • You start a job.
    • The job, if running longer, times out after 2 hours.

 

  • Example 2 - Runner timeout not configured
    • You remove the maximum_timeout parameter configuration from a runner.
    • You set the Maximum job timeout for a project to 2 hours.
    • You start a job.
    • The job, if running longer, times out after 2 hours.

 

  • Example 3 - Runner timeout smaller than project timeout
    • You set the maximum_timeout parameter for a runner to 30 minutes.
    • You set the Maximum job timeout for a project to 2 hours.
    • You start a job.
    • The job, if running longer, times out after 30 minutes.

 

Working with Tags

Using Tags Effectively

job_specific:
       tags:
         - docker
         - linux
       script:
         - echo "This job only runs on runners with these tags

 

Setting Concurrent Jobs

Configuring Concurrency in the config.toml File

# Set maximum concurrent jobs
      sudo gitlab-runner start --concurrent=4
      # If needed , add environment variables to runner
      sudo gitlab-runner run --env "CUSTOM_VAR=v

 

Handling Missing Tokens

If you've lost the token and can't access the locations above, you have two options:

Option 1: Reset the Runner's Authentication Token (API Method)

You can generate a new authentication token for an existing runner using the API. This invalidates the old token, so the runner will need to be updated with the new one.

bash

# Reset token for a specific runner (requires runner ID)
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
  "https://gitlab.example.com/api/v4/runners/<runner_id>/reset_authentication_token"

The response will include the new token:

json

{ "token": "glrt-xxxxxxxxxxxx", "token_expires_at": null }

 

Option 2: Create a New Runner

If you can't reset the token or don't know the runner ID:

  • Go to Settings > CI/CD > Runners.
  • Click New project runner (or group/instance runner).
  • Configure it with the same tags and settings.
  • Copy the new token immediately.
  • Update your runner configuration with the new token.
  • Delete the old runner from the UI.

 

Picking Up Dropped Jobs

If jobs aren't picked up:

  • Check runner status: gitlab-runner status.
  • Verify registration: Ensure token is correct in config.toml.
  • Check tags: Make sure job tags match runner tags.
  • Check logs: sudo gitlab-runner --debug run.

 

Security Notes

  • Tokens are stored in config.toml. Keep this file secure.
  • Use project-specific runners for isolated access.
  • Regularly update GitLab Runner for security patches.
  • To ensure runners don't reveal sensitive information, you can configure them to only run jobs on protected branches, or jobs that have protected tags.
  • Runners configured to run jobs on protected branches can optionally run jobs in merge request pipelines.
    • In the top bar, select Search or go to and find your project.
    • Select Settings > CI/CD.
    • Expand Runners.
    • To the right of the runner you want to protect, select Edit (pencil icon).
    • Select the Protected checkbox.
    • Select Save changes.

 

Upgrading Runners

For a stable and fully functional CI/CD setup, install the version of the GitLab Runner that matches the major version of your GitLab server. This means:

  • GitLab 17.x → Use the latest GitLab Runner 17.x
  • GitLab 18.x → Use the latest GitLab Runner 18.x

You can get the Gitlab version from Gitlab UI:

  • Log in to your GitLab instance.
  • At the bottom of the left sidebar, select Help.
  • From the dropdown menu, select Help.
  • The version number is displayed at the top of the page.
    • For example, GitLab Enterprise Editionv18.9.1-ee.

gitlab-runner --version or gitlab-runner -v

Platform Runner Version Upgrade Documentation
Linux

gitlab-runner --version or gitlab-runner -v

Upgrade Gitlab Runner 18.9 (Linux)
macOS gitlab-runner --version or gitlab-runner -v Upgrade Gitlab Runner 18.9 (macOS)
Windows

.\gitlab-runner.exe --version or .\gitlab-runner -v

Upgrade Gitlab Runner 18.9 (Windows)
Docker
  • Find your Runner's container name or ID using docker ps
  • Execute this command inside the container docker exec <container_name_or_id> gitlab-runner --version

Or, you can also run this one-off command docker run --rm gitlab/gitlab-runner --version

Upgrade Gitlab Runner 18.9 (Docker)
Kubernetes

# For Helm 2 helm search -l gitlab/gitlab-runner

# For Helm 3 helm search repo -l gitlab/gitlab-runner

Upgrade Gitlab Runner 18.9 (Kubernetes)

 


 

Details

Details

Article ID: 529
Created
Wed 4/1/26 1:30 PM
Modified
Thu 4/16/26 9:50 AM
Article Agent
The TDX agent acting as the primary point of contact for the article and is responsible for ensuring the content's accuracy on behalf of the group.