> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/define-a-docker-build-infrastructure.md).

# Set up a local runner build infrastructure

Define a CI build infrastructure on any Linux or macOS host.

You can configure CI build infrastructure on a Linux, macOS, or Windows host by installing a Harness Docker Delegate and local Harness Docker Runner. When the pipeline runs, the Harness Docker Runner runs the build actions in the environment where it is installed. The delegate handles communication between the Harness Platform and the Harness Docker Runner.

Select your operating system:

* [Set up a Linux local runner build infrastructure](#set-up-a-linux-local-runner)
* [Set up a macOS local runner build infrastructure](#set-up-a-macos-local-runner)
* [Set up a Windows local runner build infrastructure](#set-up-a-windows-local-runner)

Local runner build infrastructure is recommended for small, limited builds, such as a one-off build on your local machine. Consider [other build infrastructure options](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure.md) for builds-at-scale.

### What you will learn from this topic

By the end of this topic, you will be able to:

* Set up local runner build infrastructure on Linux, macOS, or Windows.
* Configure a CI pipeline to use local runner build infrastructure.

### Before you begin

Review the requirements for your operating system before you install the Harness Docker Delegate and Harness Docker Runner.

{% hint style="info" %}

* You can also use a [Kubernetes delegate](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/overview.md#install-the-default-delegate) instead of a Docker delegate.
* The delegate install command uses the default authentication token for your Harness account. If you want to use a different token, you can create a token and then specify it in the delegate install command's `DELEGATE_TOKEN` flag.
  {% endhint %}

### Set up a Linux local runner <a href="#set-up-a-linux-local-runner" id="set-up-a-linux-local-runner"></a>

#### Prepare machines <a href="#prepare-machines" id="prepare-machines"></a>

Review the following requirements for local runner build infrastructures:

* There is a one-to-one relationship between Harness Docker Runners and Harness Delegates. If you need to run three local hosts, each host needs a runner and a delegate.
* The Harness Docker Delegate is limited by the total amount of memory and CPU on the local host. Builds can fail if the host runs out of CPU or memory when running multiple builds. The Harness Docker Delegate has the following system requirements:
  * Default 0.5 CPU.
  * Default 1.5GB. Ensure that you provide the minimum memory for the delegate and enough memory for the host/node system.
* The machine where the delegate runs must have Docker installed.

#### Install the delegate <a href="#install-the-delegate" id="install-the-delegate"></a>

1. Refer to the [Delegate installation page](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/overview.md).
2. Copy the delegate install command and modify it as follows:
   * Add `--net=host` to the first line.
   * Add `-e DELEGATE_TAGS="DELEGATE_OS_ARCH"`, and replace `DELEGATE_OS_ARCH` with the tag corresponding to your Docker environment's architecture: `linux-amd64` or `linux-arm64`.
3. Run the modified install command on your build host machine.

#### Install the Harness Docker Runner <a href="#install-the-harness-docker-runner" id="install-the-harness-docker-runner"></a>

The Harness Docker Runner service performs the build work. The delegate needs the runner to run CI builds.

1. Download a [Harness Docker Runner executable](https://github.com/harness/harness-docker-runner/releases) corresponding to your build farm's OS and architecture.
2. (Optional) To use self-signed certificates, export `CI_MOUNT_VOLUMES` along with a comma-separated list of source paths and destination paths formatted as `path/to/source;path/to/destination`:

   ```
   export CI_MOUNT_VOLUMES="path/to/local/cert;/etc/ssl/certs/ca-certificates.crt,path/to/local/cert2;/etc/ssl/certs/cacerts.pem"
   ```

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>If your pipelines have STO scan steps, review the additional requirements for <a href="/security-testing-orchestration/troubleshooting-and-resources/sto-use-cases/secure-sto-pipelines/add-certs-to-delegate.md">adding custom artifacts to STO pipelines</a>.</p></div>
3. (Optional) To run the Docker Runner as a non-root user, set the `WORKING_DIR` environment variable before starting the runner. This ensures all files are created inside the specified directory only:

   ```
   export WORKING_DIR="/path/to/working/directory"
   ```

   For example:

   ```
   export WORKING_DIR="/home/nonrootuser/harness-runner"
   ```
4. Enable execution permissions for the Runner, for example:

   ```
   sudo chmod +x harness-docker-runner-linux-arm64
   ```
5. Start the runner binary, for example:

   ```
   sudo -E ./harness-docker-runner-linux-arm64 server
   ```

#### Define build infrastructure <a href="#define-build-infrastructure" id="define-build-infrastructure"></a>

After configuring the host machine, you need to [set the pipeline's build infrastructure](#set-the-pipelines-build-infrastructure).

### Set up a macOS local runner <a href="#set-up-a-macos-local-runner" id="set-up-a-macos-local-runner"></a>

#### Prepare machines <a href="#prepare-machines" id="prepare-machines"></a>

Review the following requirements for local runner build infrastructures:

* There is a one-to-one relationship between Harness Docker Runners and Harness Delegates. If you need to run three local hosts, each host needs a runner and a delegate.
* The Harness Docker Delegate is limited by the total amount of memory and CPU on the local host. Builds can fail if the host runs out of CPU or memory when running multiple builds. The Harness Docker Delegate has the following system requirements:
  * Default 0.5 CPU.
  * Default 1.5GB. Ensure that you provide the minimum memory for the delegate and enough memory for the host/node system.
* The machine where the delegate runs must have Docker installed.

#### Install the delegate <a href="#install-the-delegate" id="install-the-delegate"></a>

1. Refer to the [Delegate installation page](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/overview.md).
2. Copy the delegate install command and modify it as follows:
   * Add `-e DELEGATE_TAGS="DELEGATE_OS_ARCH"`, and replace `DELEGATE_OS_ARCH` with the tag corresponding to your Docker environment's architecture: `macos-amd64` or `macos-arm64`.
   * Add `-e RUNNER_URL=http://host.docker.internal:3000`.
3. Run the modified install command on your build host machine.

#### Install the Harness Docker Runner <a href="#install-the-harness-docker-runner" id="install-the-harness-docker-runner"></a>

The Harness Docker Runner service performs the build work. The delegate needs the runner to run CI builds.

1. Download a [Harness Docker Runner executable](https://github.com/harness/harness-docker-runner/releases) corresponding to your build farm's OS and architecture.
2. (Optional) To use self-signed certificates, export `CI_MOUNT_VOLUMES` along with a comma-separated list of source paths and destination paths formatted as `path/to/source;path/to/destination`:

   ```
   export CI_MOUNT_VOLUMES="path/to/local/cert;/etc/ssl/certs/ca-certificates.crt,path/to/local/cert2;/etc/ssl/certs/cacerts.pem"
   ```

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>If your pipelines have STO scan steps, review the additional requirements for <a href="/security-testing-orchestration/troubleshooting-and-resources/sto-use-cases/secure-sto-pipelines/add-certs-to-delegate.md">adding custom artifacts to STO pipelines</a>.</p></div>
3. (Optional) To run the Docker Runner with a custom working directory, set the `WORKING_DIR` environment variable before starting the runner. This ensures all files are created inside the specified directory only:

   ```
   export WORKING_DIR="/path/to/working/directory"
   ```

   For example:

   ```
   export WORKING_DIR="/Users/youruser/harness-runner"
   ```
4. Enable execution permissions for the Runner, for example:

   ```
   sudo chmod +x harness-docker-runner-darwin-amd64
   ```
5. Start the runner binary, for example:

   ```
   sudo -E ./harness-docker-runner-darwin-amd64 server
   ```
6. If [macOS Gatekeeper](https://support.apple.com/en-us/HT202491) stops the installation because it cannot check for malicious software, you need to modify **Security & Privacy** settings to allow this app to run.

   ![macOS Gatekeeper error message.](https://4226796345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqKtVmwAGTfGQS1MVC97G%2Fuploads%2Fgit-blob-5e3616fed113ec06379d8ece9c158553ff3c35bd%2Fdefine-a-macos-build-infrastructure-10.png?alt=media)

<details>

<summary>Allow the runner binary app to run</summary>

1. Go to **System Preferences** and select **Security & Privacy**.
2. On the **General** tab, select the lock to make changes.
3. Select **Allow** next to the `an app was blocked from loading` message.
4. Select **OK**.
5. Select **Open Anyway** next to the `not from an identified developer` message.

![](https://4226796345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqKtVmwAGTfGQS1MVC97G%2Fuploads%2Fgit-blob-bd5e220a657f41a4e5cb9239f0353ca2de00f52d%2Fdefine-a-macos-build-infrastructure-11.png?alt=media)

6. Select **Open** to confirm that you want to run the binary. If this window does not appear, rerun the binary start command.

</details>

#### Define build infrastructure <a href="#define-build-infrastructure" id="define-build-infrastructure"></a>

After configuring the host machine, you need to [set the pipeline's build infrastructure](#set-the-pipelines-build-infrastructure).

### Set up a Windows local runner <a href="#set-up-a-windows-local-runner" id="set-up-a-windows-local-runner"></a>

#### Prepare machines <a href="#prepare-machines" id="prepare-machines"></a>

Review the following requirements for Windows local runner build infrastructures:

* You need two machines *for each build host*:
  * A Windows machine where the Harness Docker Runner will run. **This machine must have Docker for Windows installed.** The Harness Docker Runner runs as an executable.
  * A Linux or macOS machine where the Harness Delegate will run. **This machine must have Docker installed.** The delegate runs as a container.
* There is a one-to-one relationship between Harness Docker Runners and Harness Delegates. If you need to run three local hosts, each host needs a runner machine and a delegate machine.
* The Harness Docker Delegate is limited by the total amount of memory and CPU on the local host. Builds can fail if the host runs out of CPU or memory when running multiple builds. The Harness Docker Delegate has the following system requirements:
  * Default 0.5 CPU.
  * Default 1.5GB. Ensure that you provide the minimum memory for the delegate and enough memory for the host/node system.

#### Install the delegate <a href="#install-the-delegate" id="install-the-delegate"></a>

1. Refer to the [Delegate installation page](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/overview.md).
2. Copy the delegate install command and modify it as follows:

   * Add `-e DELEGATE_TAGS="windows-amd64"`.
   * Add `-e RUNNER_URL=http://WINDOWS_MACHINE_HOSTNAME_OR_IP:3000`.

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p>The <code>RUNNER_URL</code> must point to the Windows machine where the Harness Docker Runner will run.</p></div>
3. Run the modified install command on the Linux or macOS machine where you want to run the delegate.

#### Install the Harness Docker Runner <a href="#install-the-harness-docker-runner" id="install-the-harness-docker-runner"></a>

The Harness Docker Runner performs the build work. The delegate needs the runner to run CI builds.

On Windows platforms, you can install the Docker Runner as a process (using a `.exe`) or a service (using a `.msi`). The advantage to installing the Docker Runner as a service is that the service automatically starts when the runner machine restarts.

{% hint style="warning" %}
Install the Harness Docker Runner on the Windows machine that you specified in the delegate's `RUNNER_URL`.
{% endhint %}

{% tabs %}
{% tab title="Install as a process (.exe)" %}

1. Download the Windows [Harness Docker Runner executable](https://github.com/harness/harness-docker-runner/releases) on the Windows machine where you want to run the Harness Docker Runner. This should be the Windows machine that you specified in the delegate's `RUNNER_URL`.
2. Use PowerShell to run these commands. Open a terminal with Administrator privileges.
3. (Optional) To use self-signed certificates, set `CI_MOUNT_VOLUMES` along with a comma-separated list of source paths and destination paths formatted as `path/to/source;path/to/destination`, for example:

   ```
   $env:CI_MOUNT_VOLUMES="C:\Users\installer\Downloads\certs;C:/Users/ContainerAdministrator/.jfrog/security/certs"
   ```

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><ul><li>With Windows, volume mapping must be folder-to-folder.</li><li>If your pipelines have STO scan steps, review the additional requirements for <a href="/security-testing-orchestration/troubleshooting-and-resources/sto-use-cases/secure-sto-pipelines/add-certs-to-delegate.md">adding custom artifacts to STO pipelines</a>.</li></ul></div>
4. (Optional) To run the Docker Runner with a custom working directory, set the `WORKING_DIR` environment variable before starting the runner. This ensures all files are created inside the specified directory only:

   ```
   $env:WORKING_DIR="C:\path\to\working\directory"
   ```

   For example:

   ```
   $env:WORKING_DIR="C:\Users\nonrootuser\harness-runner"
   ```
5. Start the runner binary:

   ```
   harness-docker-runner-windows-amd64.exe server
   ```

{% endtab %}

{% tab title="Install as a service (.msi)" %}
The advantage to installing the Docker Runner as a Windows service is that the service restarts when the runner machine restarts. This can be helpful if your workflow requires the runner machine to restart on a schedule or after certain events.

1. Download the [Windows Harness Docker Runner MSI file (`harness-docker-runner-svc.msi`)](https://github.com/harness/harness-docker-runner/releases) on the Windows machine where you want to run the Harness Docker Runner. This should be the machine that you specified in the delegate's `RUNNER_URL`.
2. Launch the downloaded `harness-docker-runner-svc.msi` file to start the installation process. Then accept the license, select **Next**, and finish the installation.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>TROUBLESHOOT WINDOWS SECURITY ISSUES</strong></p><p>By default, Windows Security does not trust external or unrecognized MSI files. To proceed with installation, you might need to authorize/trust the application or change permissions on the file.</p><p>Error codes 2502 or 2503 occur if the Windows MSI installation service is not authorized to write to the <code>C:\windows\Temp</code> folder during the installation process. To resolve this, do the following:</p><ol><li>In File Explorer, go to <code>C:\Windows</code>.</li><li>Right-click the <code>Temp</code> folder, and select <strong>Properties</strong>.</li><li>Select the <strong>Security</strong> tab, and then select <strong>Advanced</strong>.</li><li>Make sure an appropriate user is selected for <strong>Principal</strong>, such as an Administrator, and then select <strong>Full control</strong> for <strong>Basic permissions</strong>.</li><li>Select <strong>OK</strong> and then select <strong>Apply</strong>.</li><li>If a warning message appears, select <strong>Yes</strong> and <strong>Continue</strong>.</li><li>Restart or continue the installation process.</li></ol><p>If you get the error message <code>This installation package could not be opened</code>, you might need to <a href="https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc753659(v=ws.10)">change ownership of the file</a> to Administrators, allow full control, and then restart or continue the installation process. If you are not already an administrator, you might need to elevate your permissions using <a href="https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control">User Account Control (UAC)</a>.</p></div>
3. (Optional) To test the service availability, open a terminal with Administrator privileges and run:

   ```
   curl http://localhost:3000/healthz
   ```

Windows Docker Runner service logs are located at `C:\Windows\system32\harness-docker-runner-TIMESTAMP.log`. If your Windows installation does not use the default `C:\Windows\system32` file path, you can find the log files at `INSTALL_DIRECTORY\harness-docker-runner-TIMESTAMP.log`.

{% hint style="warning" %}
Do not manually start, stop, or delete the Runner service. This can cause problems with orphaned files or subprocesses.

If you need to remove the service, follow the uninstall instructions in the [Windows Harness Docker Runner MSI Readme](https://github.com/harness/harness-docker-runner?tab=readme-ov-file#uninstallation).
{% endhint %}
{% endtab %}
{% endtabs %}

#### Define build infrastructure <a href="#define-build-infrastructure" id="define-build-infrastructure"></a>

After configuring the host machines, you need to [set the pipeline's build infrastructure](#set-the-pipelines-build-infrastructure).

### Set the pipeline's build infrastructure <a href="#set-the-pipelines-build-infrastructure" id="set-the-pipelines-build-infrastructure"></a>

Edit the CI pipeline where you want to use the local runner build infrastructure.

{% tabs %}
{% tab title="Visual" %}

1. In the pipeline's **Build** stage, select the **Infrastructure** tab.
2. Select **Local** for the **Infrastructure**.
3. Select the relevant **Operating System** and **Architecture**.
4. Save your pipeline.
   {% endtab %}

{% tab title="YAML" %}
In the pipeline's build stage (`type: CI`), insert `platform` and `runtime` specifications, for example:

```yaml
- stage:
    name: build
    identifier: build
    description: ""
    type: CI
    spec:
      cloneCodebase: true
      platform:
        os: Linux
        arch: Amd64
      runtime:
        type: Docker
        spec: {}
```

* `platform`:
  * `os`: Specify `Linux`, `MacOS`, or `Windows`
  * `arch`: Specify `Amd64` or `Arm64`
* `runtime`:
  * `type`: `Docker`
  * `spec`: `{}`
    {% endtab %}
    {% endtabs %}

{% hint style="info" %}
**DELEGATE SELECTORS**

Although you must install a delegate to use the local runner build infrastructure, you can choose to use a different delegate for executions and cleanups in individual pipelines or stages. To do this, use [pipeline-level delegate selectors](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md#pipeline-delegate-selector) or [stage-level delegate selectors](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md#stage-delegate-selector).

Delegate selections take precedence in the following order:

1. Stage
2. Pipeline
3. Platform (build machine delegate)

This means that if delegate selectors are present at the pipeline and stage levels, then these selections override the platform delegate, which is the delegate that you installed on the build machine. If a stage has a stage-level delegate selector, then it uses that delegate. Stages that do not have stage-level delegate selectors use the pipeline-level selector, if present, or the platform delegate.

For example, assume you have a pipeline with three stages called `alpha`, `beta`, and `gamma`. If you specify a stage-level delegate selector on `alpha` and you do not specify a pipeline-level delegate selector, then `alpha` uses the stage-level delegate, and the other stages (`beta` and `gamma`) use the platform delegate.

<details>

<summary>Early access feature: Use delegate selectors for codebase tasks</summary>

Delegate selectors for CI codebase tasks are behind the feature flag `CI_CODEBASE_SELECTOR`. Contact [Harness Support](mailto:support@harness.io) to enable the feature.

By default, delegate selectors are not applied to delegate-related CI codebase tasks.

With this feature flag enabled, Harness uses your [delegate selectors](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md) for delegate-related codebase tasks. Delegate selection for these tasks takes precedence in order of [pipeline selectors](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md#pipeline-delegate-selector) over [connector selectors](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md#infrastructure-connector).

</details>
{% endhint %}

#### Override Image Connector <a href="#override-image-connector" id="override-image-connector"></a>

By default, [Harness pulls certain images from public Docker Hub repos](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/harness-ci.md) that are needed to run a build. You can override this by using a [Docker connector that downloads the images from the Harness Container Image Registry](/harness-platform/use-harness-platform/connectors/artifact-repositories/add-a-docker-registry-connector/connect-to-harness-container-image-registry-using-docker-connector.md) instead. This option is useful when your default Delegate cannot access the public registry (for example, due to security policies in your organization or if your infrastructure is running in a private cloud).

#### How it works

Refer to the YAML snippet below to see how this is used. Harness Docker Runner would use the referenced Docker connector to authenticate and pull CI images.

```yaml
- stage:
    name: build
    identifier: build
    description: ""
    type: CI
    spec:
      cloneCodebase: true
      platform:
        os: Linux
        arch: Amd64
      runtime:
        type: Docker
        spec: 
          harnessImageConnectorRef: account.docker_private_ciplay
```

{% hint style="info" %}
This configuration applies to Harness CI VM Runners used for Windows build VMs.
{% endhint %}

You can make custom CA certificates available inside all build step containers (including the `drone/git` clone container) on **Windows build VMs** by setting the `DRONE_RUNNER_VOLUMES` environment variable when starting the VM runner.

#### Example <a href="#example" id="example"></a>

```bash
docker run -d \
  -v /runner:/runner \
  -p 3000:3000 \
  -e DRONE_RUNNER_VOLUMES=/custom-cert:/git/mingw64/ssl/certs \
  <your_registry_domain>/drone/drone-runner-aws:latest \
  delegate --pool /runner/pool.yml
```

{% hint style="info" %}
**Certificate requirements**

* The certificate file inside `/custom-cert` must be named **`ca-bundle.crt`**.
* The `drone-git` container on Windows expects the certificate to be available at **`C:\git\mingw64\ssl\certs\ca-bundle.crt`**.
* The `DRONE_RUNNER_VOLUMES` path must use **Linux-style syntax**. Use `/` as the path separator and omit the drive letter (`C:`), even though the build VM runs Windows.
  {% endhint %}

### Next steps

* [CI Build stage settings](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/ci-stage-settings.md): Configure the build stage that uses this infrastructure.
* [Stream build logs](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/stream-ci-build-logs-to-observability-backend.md): Export CI build step logs from a self-managed Harness Delegate

{% @harness-feedback/feedback %}
