Skip to main content
Harness CI 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.

How it works

  • The Harness Delegate and VM runner run in your network. Harness documents how to install the Delegate and its system 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. 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.

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.
  • 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.
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. For token lifetimes and rotation, see Manage service accounts.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:
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.
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.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:
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.
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.
  • Run the Delegate and runner where they can reach your Orka network (recommended). Connect your network to MacStadium with a site-to-site VPN, 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. 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.

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.
  • 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.
  • 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.