On Premise
Cirun supports spinning up runners on your own infrastructure. The agent picks
one of three executor backends based on the host and your .cirun.yml:
| Executor | Host requirement | Runner is a... |
|---|---|---|
meda (default on Linux) | Linux with KVM | lightweight VM (cloud-hypervisor) |
lume (default on macOS) | Apple Silicon (Mac Mini, Mac Pro, MacBook) | macOS VM (Apple Virtualization framework) |
docker | Linux with Docker, or macOS with Docker Desktop | container |
The setup is simple and can be done in a few minutes. You install
cirun-agent on your machine, and it connects to Cirun's API to spin up
on-demand ephemeral runners for GitHub Actions.
Setting up cirun-agent
-
Create an API token on the Cirun Dashboard.
-
Install the cirun-agent:
curl --proto '=https' --tlsv1.2 -LsSf https://raw.githubusercontent.com/cirunlabs/cirun-agent/refs/heads/main/install.sh | sh -
Install and start as a system service (recommended):
# Linux (systemd)export CIRUN_API_TOKEN=YOUR_TOKENsudo -E cirun-agent --install-service# macOS (launchd)export CIRUN_API_TOKEN=YOUR_TOKENcirun-agent --install-serviceThe service starts on boot and restarts on failure. Logs go to the system journal (Linux) or
~/Library/Logs/cirun-agent.log(macOS).Alternative: run manually in the foreground:
export CIRUN_API_TOKEN=YOUR_TOKENcirun-agent -
Create a
.cirun.ymlfile in your repository. Pick the executor that matches your host:macOS VM (lume):
runners:- name: cirun-macos-runnercloud: on_preminstance_type: 8vcpu-8gb-100gbmachine_image: "cirunlabs/macos-sequoia-xcode:16.4"region: RegionOnelabels:- cirun-macos-runnertipMatch
instance_typeto the template's native size. The agent resizes the macOS APFS disk vialume, which truncates and breaks boot if you request a size smaller than the source. Thexcode:16.4template ships as 8 vCPU / 8 GB / 100 GB.Linux VM (meda):
runners:- name: cirun-linux-runnercloud: on_preminstance_type: 8vcpu-8gb-75gbmachine_image: "ubuntu:latest"region: RegionOnelabels:- cirun-linux-runnerDocker container (linux or macOS host):
runners:- name: cirun-docker-runnercloud: on_preminstance_type: 4vcpu-8gb-50gbmachine_image: "ghcr.io/cirunlabs/cirun-docker-runner-image:latest"region: RegionOneextra_config:executor: docker# Optional: start dockerd inside the container so jobs can# `docker build` / `docker run` (docker-in-docker).privileged: truelabels:- cirun-docker-runnerThe
cirun-docker-runner-imageis a multi-arch (amd64 + arm64) Ubuntu 24.04 image with the GitHub Actions runner deps and Docker pre-installed.GPU Docker container (Linux host with NVIDIA):
runners:- name: cirun-gpu-docker-runnercloud: on_preminstance_type: 4vcpu-8gb-50gbmachine_image: "ghcr.io/cirunlabs/cirun-docker-runner-image:gpu"region: RegionOneextra_config:executor: dockergpu: alllabels:- cirun-gpu-docker-runnerThe
:gputag adds CUDA 13.2.1 runtime libs on top of the same toolchain. Host needsnvidia-container-toolkitinstalled;gpu: allis passed through todocker run --gpus. -
Configure your workflow to use the runner:
runs-on: cirun-linux-runner--${{ github.run_id }}Make sure you have installed the Cirun GitHub App and marked the repository as active on the Cirun Dashboard.
extra_config reference
Per-runner knobs under extra_config: in .cirun.yml. All are optional;
all apply to the docker executor unless noted.
| Key | Type | Effect |
|---|---|---|
executor | meda | lume | docker | Override the host default. Required if the host supports more than one (e.g. Linux with Docker installed but you want a VM). |
privileged | bool | Run the container with --privileged. Required for docker-in-docker. |
docker_socket_mount | bool | Bind-mount /var/run/docker.sock from the host into the runner so jobs share the host daemon (docker-out-of-docker). |
gpu | string (e.g. all) | Pass through to docker run --gpus. Requires nvidia-container-toolkit on the host. |
Capacity planning
Unlike cloud runners (where capacity is the provider's problem), on-prem runners share the finite CPU / RAM / disk of your host. Two knobs let you shape concurrency:
Cap concurrent runners with --max-runners
cirun-agent will not start more runners (VMs or containers, depending on
the executor) than --max-runners allows; extra jobs queue until a slot
frees up.
export CIRUN_API_TOKEN=YOUR_TOKEN
cirun-agent --max-runners 5
Defaults:
- macOS:
2(Apple Virtualization framework caps concurrent VMs at 2 on most Apple Silicon hardware). - Linux: unlimited — set this explicitly to match your host's CPU/RAM.
Re-install the service after changing the flag so the new limit is picked up:
export CIRUN_API_TOKEN=YOUR_TOKEN
sudo -E cirun-agent --install-service --max-runners 5 # Linux
cirun-agent --install-service --max-runners 5 # macOS
Zero-latency jobs with idle runners
Cloud runners take a couple of minutes to provision, but on-prem runners
provision in seconds — and even those seconds disappear if you keep a
warm pool with idle:. An idle runner is
already booted and registered with GitHub, so a job picks it up instantly.
runners:
- name: cirun-macos-runner
cloud: on_prem
instance_type: 8vcpu-8gb-100gb
machine_image: "cirunlabs/macos-sequoia-xcode:16.4"
region: RegionOne
labels:
- cirun-macos-runner
idle:
replicas: 2
Keep replicas ≤ --max-runners (otherwise the idle pool can't reach its
target). When using idle runners, drop the --${{ github.run_id }} suffix
on runs-on — see Idle Runners for full
details and time-windowed schedules.