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

# Harness CI on Orka: Orka-side setup

> Prepare Orka for Harness CI macOS builds: a service account, a VM image and config, port mapping, and network access for the Harness Delegate and runner.

[Harness CI](https://developer.harness.io/docs/continuous-integration/) can run macOS builds on Orka VMs. Harness builds and documents its side of the integration: the Harness Delegate, the VM runner, and the pipeline configuration. This page covers what you set up in Orka so that Harness can deploy VMs and reach them. For the Harness side, including the base image bootstrap daemon and `pool.yml`, see Harness's [Set up a macOS VM build infrastructure with Orka](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure/define-macos-build-infra-with-orka).

## How it works

* The [Harness Delegate](https://developer.harness.io/docs/platform/delegates/delegate-concepts/delegate-overview) and VM runner run in your network. Harness documents how to [install the Delegate](https://developer.harness.io/docs/platform/delegates/install-delegates/overview) and its [system requirements](https://developer.harness.io/docs/platform/delegates/delegate-concepts/delegate-requirements).
* The runner keeps a warm pool of ready VMs, or deploys them on demand, up to a limit you set. It calls the Orka API with a service account token and deploys each VM from a VM config or directly from an image.
* At boot, a launchd daemon in the image reads a startup script that the runner passes through [VM metadata](https://docs.macstadium.com/orka/orka-resources/working-with-vm-metadata.md). The script starts the Harness agent, lite-engine, which runs the build.
* The runner reaches lite-engine at the node's IP address on TCP port 9079 or 9080, which Orka forwards to the VM.
* When the build finishes, the runner deletes the VM.

Orka doesn't provide an SDK. The Harness integration, like the other Orka integrations, uses the [Orka REST API](https://macstadium.github.io/orka-api-docs/).

## Prerequisites

* An Orka cluster with Apple silicon nodes, on Orka 3.x or 4.0. The integration deploys VMs from OCI images.
* A host for the Harness Delegate and runner that can reach the Orka API and your Orka nodes. See [Network access](#network-access).
* An Orka administrator to create the service account.

## Set up Orka for Harness

**1. Create a service account and token**

Create a service account for Harness, then generate a token for it. Use a service account token, not a user token: user tokens expire after about an hour.

```shell theme={null}
orka sa create harness
orka sa token harness
```

The token lasts one year by default. Give it to the runner as the `ORKA_TOKEN` environment variable, as Harness describes in [Start the runner](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure/define-macos-build-infra-with-orka#start-the-runner). For token lifetimes and rotation, see [Manage service accounts](https://docs.macstadium.com/orka/orka-cluster-access/orka-cluster-manage-service-accounts.md).

On Orka 3.x, use `orka3` in place of `orka`.

**2. Choose a namespace**

The runner deploys VMs into the namespace set in `pool.yml`. Orka namespace names must start with `orka-`, so a namespace such as `harness-ci` can't exist on an Orka cluster, and the runner fails because the namespace isn't found.

To use the default namespace, set `namespace: orka-default` in `pool.yml`. To keep Harness builds on their own nodes, create a namespace, move nodes into it, and give the service account access:

```shell theme={null}
orka namespace create orka-harness-ci
orka node namespace <NODE_NAME> orka-harness-ci
orka rbac add-subject --role dev --namespace orka-harness-ci --serviceaccount orka-default:harness
```

On Orka 3.x, use `orka3 rolebinding add-subject --namespace orka-harness-ci --serviceaccount orka-default:harness` for the last command. For more on namespaces, see [Namespace management](https://docs.macstadium.com/orka/orka-cli-reference/namespace-management.md).

**3. Prepare a VM image**

Start from an Orka image, for example `ghcr.io/macstadium/orka-images/tahoe:latest`, and add the tools your builds need, such as Xcode. Then add the Harness bootstrap daemon, as described in Harness's [Prepare your Orka base image](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure/define-macos-build-infra-with-orka#prepare-your-orka-base-image).

The image needs:

* **Orka VM Tools**, which serve the VM metadata the daemon reads. MacStadium's Orka images include them. If you build your own base image, install them.
* **Homebrew**, at `/opt/homebrew`. The runner's startup script installs lite-engine under `/opt/homebrew/bin`.

Push the finished image to an OCI registry with `orka vm push`, and wait for the push to finish (`orka vm get-push-status <JOB_NAME>`) before you use the image. To make VMs start faster, cache it on the nodes Harness uses with `orka imagecache add`.

**4. Create a VM config (optional)**

The runner can deploy from an image directly, or from a VM config. To use a VM config, create one:

```shell theme={null}
orka vm-config create harness-macos --image <IMAGE> --cpu 4 --memory 8
```

Use `--tag` to keep Harness builds on specific nodes, and `--tag-required` to keep them off other nodes. If you deploy from an image instead, the runner's `pool.yml` has matching `tag` and `tag_required` settings. For all options, see [VM deployment and configuration](https://docs.macstadium.com/orka/orka-cli-reference/vm-deployment-and-configuration.md).

**5. Plan the port mapping**

On each deploy, the runner asks Orka to forward TCP port 9079 on the node to lite-engine on port 9079 in the VM. If 9079 is already taken on the node, it retries with node port 9080. A node runs at most 2 VMs, so the two ports cover it. Don't map 9079 or 9080 to anything else on nodes that Harness uses.

If both ports are taken on the chosen node, the deploy fails with `Requested reserved port range not available on the chosen node(s).`

## Network access

The runner must reach the Orka API and TCP ports 9079 and 9080 on every node it deploys to. Orka maps ports and NATs traffic to the VM, but it doesn't provide public ingress to VMs.

> [tab] Hosted by MacStadium
>
> * **Run the Delegate and runner where they can reach your Orka network (recommended).** Connect your network to MacStadium with a [site-to-site VPN](https://docs.macstadium.com/iaas/connecting-to-other-clouds/other-clouds.md), or run the runner in a cloud you've connected. Nothing is exposed to the internet.
> * **Public IP addresses.** For a small environment, you can map public IP addresses to the Orka API and the nodes on your firewall, and allow only Harness's addresses. See [Allow specific IPs to access MacStadium via the internet](https://docs.macstadium.com/iaas/cisco-firewalls/allowing-specific-ips-to-access-macstadium-via-internet.md). This doesn't scale well as you add nodes.
> * **A tunnel you run.** Tools such as Tailscale, Cloudflare Tunnel, or ngrok can give the runner a path to the VMs without a VPN client. You set up and support these yourself.

> [tab] Self-managed (on-premises)
>
> * **Run the Delegate and runner on your network,** with routes to the Orka API and the node IP addresses. This is the simplest setup.
> * If the runner is elsewhere, expose the Orka API and the mapped node ports through your own network edge, or use a tunnel you run. For exposing the Orka API, see [Orka on-premises](https://docs.macstadium.com/orka/orka-on-aws-and-on-prem/orka-on-prem-getting-started.md#exposing-the-orka-api-service).

## Troubleshooting

* **The runner can't find the namespace.** The namespace in `pool.yml` doesn't exist. Orka namespace names start with `orka-`. See [Choose a namespace](#choose-a-namespace).
* **Different images or VM configurations for different builds.** Define one pool per image or VM config in `pool.yml`, then choose the pool by name in each Build stage. Each stage uses one pool.
* **A deploy fails with `Requested reserved port range not available on the chosen node(s).`** Ports 9079 and 9080 are both taken on the node, usually because it's already running 2 VMs. See [Plan the port mapping](#plan-the-port-mapping).
* **Choosing a Delegate per pipeline or stage.** If you run more than one Delegate and runner, for example one per Orka cluster, and want to pick one for each pipeline or stage, Harness's delegate selectors for VM build infrastructure are behind a feature flag. Ask Harness Support to enable `CI_ENABLE_VM_DELEGATE_SELECTOR` on your account. With a single Delegate and runner, you don't need it.

For Harness-side issues, such as the Delegate or runner not connecting, see Harness's [troubleshooting section](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure/define-macos-build-infra-with-orka#troubleshoot-self-managed-vm-build-infrastructure).

## Related

* [Set up a macOS VM build infrastructure with Orka](https://developer.harness.io/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure/define-macos-build-infra-with-orka) (Harness)
* [Harness Delegate overview](https://developer.harness.io/docs/platform/delegates/delegate-concepts/delegate-overview)
* [Delegate installation options](https://developer.harness.io/docs/platform/delegates/install-delegates/overview)
* [Delegate system requirements](https://developer.harness.io/docs/platform/delegates/delegate-concepts/delegate-requirements)
* [Which Harness build infrastructure is right for me](https://developer.harness.io/docs/continuous-integration/use-ci/set-up-build-infrastructure/which-build-infrastructure-is-right-for-me)
* [Orka API reference](https://macstadium.github.io/orka-api-docs/)
* [Bootstrap VMs with User Data](https://docs.macstadium.com/orka/orka-resources/userdata.md)


## Related topics

- [3. Orka side of the AWS VPN tunnel](https://docs.macstadium.com/orka/networking-with-orka-at-macstadium/3-aws-orka-side-of-the-vpn-tunnel.md)
- [3. Orka Side of the GCP VPN Tunnel](https://docs.macstadium.com/orka/networking-with-orka-at-macstadium/3-orka-side-of-the-gcp-vpn-tunnel.md)
- [1. AWS Side of the VPN Tunnel](https://docs.macstadium.com/orka/networking-with-orka-at-macstadium/1-aws-side-of-the-vpn-tunnel.md)
- [1. GCP Side of the VPN Tunnel](https://docs.macstadium.com/orka/networking-with-orka-at-macstadium/1-gcp-side-of-the-vpn-tunnel.md)
- [Orka CI/CD integrations quick start guide](https://docs.macstadium.com/orka/quick-start-guides/cicd-integrations-quick-start.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.