> ## Documentation Index
> Fetch the complete documentation index at: https://docs.futurex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure GitLab Runner

> Instructions to configure a GitLab Runner for secure, containerized code signing workflows.

## What is GitLab Runner?

GitLab Runner executes your CI/CD pipeline jobs either on a dedicated host outside your GitLab instance or on the same host as your GitLab instance. For CryptoHub code signing, you need a runner that can pull Docker images from public registries (i.e., Docker Hub and the Futurex public registry), then execute build and signing jobs in isolated containers. This ensures clean, reproducible builds and keeps your signing credentials off developer workstations.

In this section, you install GitLab Runner on a Linux machine, register it with your GitLab project, and configure the Docker executor to handle both MinGW cross-compilation jobs and CryptoHub CLI signing jobs. Once complete, any pipeline run will automatically route build jobs (tagged `mingw`) and sign jobs (tagged `codesign`) to this runner.

## Install Docker

**Why:** GitLab Runner's Docker executor spawns ephemeral containers for each job. Without Docker, the runner cannot execute pipeline jobs.

If Docker isn't installed, add the official Docker repository and install:

<Warning>
  As an extra precausion, run the following command to uninstall all conflicting packages before proceeding with the below commands to install Docker.

  ```Plaintext wrap theme={null}
  sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)
  ```
</Warning>

```bash expandable lines wrap title="Bash" theme={null}
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
```

Verify Docker is running:

```bash expandable lines wrap title="Bash" theme={null}
sudo docker run hello-world
```

## Install GitLab Runner

Add the GitLab Runner repository and install:

```bash expandable lines wrap title="Bash" theme={null}
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt install -y gitlab-runner
```

Verify the installation:

```bash expandable lines wrap title="Bash" theme={null}
gitlab-runner --version
```

Expected output: `Version 17.x.x` (or newer)

## Register the runner with your GitLab instance

Run the registration wizard:

```bash expandable lines wrap title="Bash" theme={null}
sudo gitlab-runner register

Provide the following values when prompted:

<table>
  <thead>
    <tr>
      <th>Prompt</th>
      <th>Value</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>GitLab instance URL</strong></td>
      <td><code>https://gitlab.com</code> (or your instance URL)</td>
      <td>Include <code>https://</code></td>
    </tr>
    <tr>
      <td><strong>Registration token</strong></td>
      <td><code>[token from GitLab UI]</code></td>
      <td>Find in <strong>Settings > CI/CD > Runners</strong></td>
    </tr>
    <tr>
      <td><strong>Description</strong></td>
      <td><code>codesign-runner</code></td>
      <td>Appears in GitLab UI; be descriptive</td>
    </tr>
    <tr>
      <td><strong>Tags</strong></td>
      <td><code>mingw,codesign</code></td>
      <td>Comma-separated; critical for job routing</td>
    </tr>
    <tr>
      <td><strong>Maintenance note</strong></td>
      <td><code>[leave empty]</code></td>
      <td>Optional; press Enter to skip</td>
    </tr>
    <tr>
      <td><strong>Executor</strong></td>
      <td><code>docker</code></td>
      <td>Type <code>docker</code> exactly</td>
    </tr>
    <tr>
      <td><strong>Default Docker image</strong></td>
      <td><code>alpine:latest</code></td>
      <td>Fallback image; rarely used in practice</td>
    </tr>
  </tbody>
</table>

**Why tags matter:** GitLab routes jobs to runners based on tags. A job tagged `mingw` will only run on runners with that tag. No tag match = job stuck in "pending" until the heat death of the universe.

**Example registration session:**

Runtime platform: arch=amd64 os=linux
Enter the GitLab instance URL: https://gitlab.com
Enter the registration token: glrt-a8c3eFx9...
Enter a description: codesign-runner
Enter tags for the runner (comma-separated): mingw,codesign
Enter optional maintenance note: 
Registering runner... succeeded
Enter an executor: docker
Enter the default Docker image: alpine:latest
Runner registered successfully.
```

## Configure Docker executor settings

Edit the runner configuration to optimize image handling and security:

```bash expandable lines wrap title="Bash" theme={null}
sudo nano /etc/gitlab-runner/config.toml
```

Locate the `[[runners]]` section for your newly registered runner. Add or modify the following under `[runners.docker]`:

```none expandable lines wrap title="None" theme={null}
[[runners]]
  name = "codesign-runner"
  url = "https://gitlab.com"
  token = "glrt-a8c3eFx9..."
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "alpine:latest"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    pull_policy = ["if-not-present"]
    allowed_images = ["*"]
    allowed_services = ["*"]
```

Key settings explained:

* `pull_policy = ["if-not-present"]`: Reuses cached images; reduces pull time from 30s to \<1s after first run
* `allowed_images = ["*"]`: Permits any Docker image; lock this down in production       (`["openturns/*", "docker-registry.futurex.com/*"]`)
* `volumes = ["/cache"]`: Persists build artifacts between jobs (optional but recommended)

Save and exit (`Ctrl+X`, `Y`, `Enter`).

## Configure Futurex Docker registry authentication

<Note>
  Before you can authenticate to the Futurex Docker registry, contact the [Futurex support team](https://www.futurex.com/support) to request access. Futurex must complete backend provisioning and issue you registry credentials before this command will succeed.
</Note>

Create a Docker config for the `gitlab-runner` user:

```bash expandable lines wrap title="Bash" theme={null}
sudo -u gitlab-runner docker login docker-registry.futurex.com
```

Enter the registry credentials provided by Futurex support when prompted. This stores authentication in `/home/gitlab-runner/.docker/config.json`, which the runner automatically uses.

## Restart the runner service

Apply configuration changes:

```bash expandable lines wrap title="Bash" theme={null}
sudo gitlab-runner restart
```

Verify the runner is active:

```bash expandable lines wrap title="Bash" theme={null}
sudo gitlab-runner status
```

Expected output: `gitlab-runner: Service is running`

## Verify runner registration in GitLab UI

<Steps>
  <Step>
    Go to your GitLab project.
  </Step>

  <Step>
    Select**Settings** > **CI/CD**.
  </Step>

  <Step>
    Expand **Runners**.
  </Step>

  <Step>
    Confirm your runner (`codesign-runner`) appears with a green status indicator.
  </Step>

  <Step>
    Verify tags: `mingw`, `codesign`.
  </Step>
</Steps>

<Warning>
  If the runner shows a red indicator, check `/var/log/syslog` for error messages:

  ```Plaintext wrap theme={null}
  sudo tail -f /var/log/syslog | grep gitlab-runner
  ```
</Warning>

<Check>
  Result:

  You now have a working GitLab Runner that can:

  * Pull images from Docker Hub (`openturns/archlinux-mingw`)
  * Pull images from the Futurex registry (`docker-registry.futurex.com/kmes-cli:1.9.2-2`)
  * Execute jobs tagged `mingw` (build stage) or `codesign` (sign stage)
</Check>

**Test it:** Trigger a pipeline in your GitLab project. Jobs tagged `mingw` or `codesign` should start immediately (or within seconds).

## Next steps

* **Add the signing pipeline:** Configure `.gitlab-ci.yml` to use the `mingw` and `codesign` tags (covered in the next section).
* **Lock down image access:** In production, replace `allowed_images = ["*"]` with an explicit allowlist.
  -**Monitor runner logs:** Watch for failures: `sudo journalctl -u gitlab-runner -f`
