RelayRunner docs: Your machines Page: https://relayrunner.app/docs/runners/self-hosted Markdown: https://relayrunner.app/docs/runners/self-hosted.md All pages: https://relayrunner.app/docs/llms.txt Other pages (Markdown): - Changelog: https://relayrunner.app/docs/changelog.md - CLI changelog: https://relayrunner.app/docs/changelog/cli.md - CI traces in your observability tool: https://relayrunner.app/docs/changelog/opentelemetry-traces.md - Platform changelog: https://relayrunner.app/docs/changelog/platform.md - Retries, queueing and provider usage: https://relayrunner.app/docs/changelog/retries-queueing-and-provider-usage.md - Optimized checks: https://relayrunner.app/docs/concepts/optimized-checks.md - Principles: https://relayrunner.app/docs/concepts/principles.md - Routing: https://relayrunner.app/docs/concepts/routing.md - Runner order: https://relayrunner.app/docs/concepts/runner-order.md - Add a provider: https://relayrunner.app/docs/contribute/add-provider.md - Feedback: https://relayrunner.app/docs/contribute/feedback.md - Activity and history: https://relayrunner.app/docs/dashboard/activity.md - Performance: https://relayrunner.app/docs/dashboard/performance.md - Remove RelayRunner: https://relayrunner.app/docs/dashboard/remove.md - Signals: https://relayrunner.app/docs/dashboard/signals.md - Telemetry: https://relayrunner.app/docs/dashboard/telemetry.md - Usage and savings: https://relayrunner.app/docs/dashboard/usage.md - Workspaces and members: https://relayrunner.app/docs/dashboard/workspaces.md - Set up with an agent: https://relayrunner.app/docs/get-started/agents.md - How it works with GitHub Actions: https://relayrunner.app/docs/get-started/github-actions.md - Install the CLI: https://relayrunner.app/docs/get-started/install.md - Move your workflows over: https://relayrunner.app/docs/get-started/move-over.md - Route GitHub Actions jobs to any runner: https://relayrunner.app/docs/get-started/overview.md - Quickstart: https://relayrunner.app/docs/get-started/quickstart.md - Keep up with coding agents: https://relayrunner.app/docs/guides/agent-surge.md - Run CI on your laptop while you work: https://relayrunner.app/docs/guides/laptop-ci.md - macOS and iOS builds on your Mac: https://relayrunner.app/docs/guides/mac-builds.md - Spend controls: https://relayrunner.app/docs/guides/spend-controls.md - Share your team's machines: https://relayrunner.app/docs/guides/team-machines.md - RelayRunner API: https://relayrunner.app/docs/reference/api.md - CLI: https://relayrunner.app/docs/reference/cli.md - Errors: https://relayrunner.app/docs/reference/errors.md - FAQ: https://relayrunner.app/docs/reference/faq.md - GitHub App: https://relayrunner.app/docs/reference/github-app.md - Runner labels: https://relayrunner.app/docs/reference/labels.md - MCP server: https://relayrunner.app/docs/reference/mcp.md - Data and privacy: https://relayrunner.app/docs/reference/privacy.md - relay.yml inputs: https://relayrunner.app/docs/reference/relay-inputs.md - Repo config: https://relayrunner.app/docs/reference/repo-config.md - Security: https://relayrunner.app/docs/reference/security.md - Troubleshooting: https://relayrunner.app/docs/reference/troubleshooting.md - GitHub-hosted: https://relayrunner.app/docs/runners/github.md - Hosted providers: https://relayrunner.app/docs/runners/hosted.md - Providers: https://relayrunner.app/docs/runners/providers.md - Your machines: https://relayrunner.app/docs/runners/self-hosted.md (this page) --- # Your machines > Turn computers you own into GitHub Actions runners with the CLI. Any Mac or Linux computer can take jobs: your laptop, a Mac mini under the desk, an old gaming PC, a home server. Connect it with the CLI and it joins the self-hosted step of every workspace you're in. ## Connect a machine ```sh npx relayrunner connect ``` The first run signs the machine in. After that, the machine is online while `connect` runs, and the terminal shows each job as it runs. Ctrl-C takes it offline. Jobs run in GitHub's official runner, set up fresh for each job. The machine needs no runner setup of its own. Where a job runs depends on the machine: - **On a Mac with Apple silicon**, each job runs in its own Linux VM, away from your files. See [Isolated jobs on a Mac](#isolated-jobs-on-a-mac). - **On Linux or an Intel Mac**, jobs run on the machine itself, as the user who started `connect`. ## Labels Every machine has the label `self-hosted`, plus the OS and architecture its jobs run on: `macOS` or `Linux`, and `ARM64` or `X64`. A Mac that runs jobs in Linux VMs has the label `Linux`, and `macOS` too when you connect it with `--macos`. A relay's `machine` input lists the labels a machine must have, all of them: | `machine:` | Runs on | | ------------- | --------------------------------------------- | | `self-hosted` | Any machine | | `Linux` | Linux machines, and Macs that run jobs in VMs | | `macOS` | Macs that take macOS jobs | | `Linux, X64` | Intel or AMD Linux machines | ## Who can run jobs on it A new machine only runs jobs you started (**only me**). To let teammates' and bots' jobs run on it too, share it with **anyone** in the workspace: ```sh relayrunner share anyone # or only-me ``` You can also change it from the sharing icon on the machine's card on the **Runners** page. Only the machine's owner can change it. "Anyone" only covers jobs from repos the machine's owner can open on GitHub, so sharing a machine never gives it code you couldn't already see. See [Share your team's machines](/docs/guides/team-machines). ## Pause Pausing keeps a machine connected but stops new jobs reaching it. A job it's already running finishes. ```sh relayrunner pause relayrunner resume ``` Press `p` in the `connect` terminal, or use the machine's ⋯ menu on the Runners page. Anyone in the workspace can pause a machine. ## Jobs at once A machine runs up to 2 jobs at once when it has 8 or more CPU cores, otherwise 1. Change it with `relayrunner connect --concurrency `. Each job gets its own VM or its own copy of the runner, so jobs never share a workspace. When every slot is busy, the next job goes to another machine or falls through to the next step in your runner order. With no next step, it waits for a free slot. ## Isolated jobs on a Mac On a Mac with Apple silicon, each job runs in its own Linux VM. The VM sees none of your files, can reach the internet but not your Mac or your local network, and is deleted when the job ends. You need macOS 26 and Apple's [container](https://github.com/apple/container/releases) tool, started once with `container system start`. Without it, `connect` still works: jobs run on the Mac itself, where they can read your files, and `connect` tells you so each time it starts. The first run takes a couple of minutes to prepare the image jobs start from. After that a VM starts in a few seconds. ### What's in the VM The VM has the everyday tools a job written for `ubuntu-latest` expects: Git and Git LFS, Docker with Compose and Buildx, Node with npm, Python with pip, compilers and `make`, `curl`, `wget`, `jq`, `zip` and the `gh` CLI. Jobs with `services:` or `container:` run too. For a specific version of Node or Python, or another language such as Go, Java, Ruby or Rust, use its `setup-*` action as you would on GitHub. The VM is ARM, so a job that needs x64 binaries should stay on `ubuntu-latest`. To start from your own runner image, pass `--image `. Your image is used with the tools it has. ### macOS jobs In a VM, jobs run on Linux, so the Mac's labels are `Linux` and `ARM64` and it takes jobs written for `ubuntu-latest`. To take macOS jobs such as Xcode builds too, add `--macos`: ```sh npx relayrunner connect --macos ``` Linux jobs still run in a VM. macOS jobs run on the Mac itself, as you, so route them only from repos you trust. A job that names neither OS goes by its GitHub fallback, so one written for `ubuntu-latest` runs in the VM. ### The size of each job Each VM gets an even share of the Mac's CPU cores, and of half its memory, so the Mac stays usable while jobs run. A Mac with 14 cores and 36 GB running 2 jobs at once gives each job 7 CPUs and 9 GB. To give every job a fixed size, like a hosted runner's, set it: ```sh npx relayrunner connect --cpus 4 --memory 16 ``` That runs as many 4 CPU, 16 GB jobs at once as fit. `--concurrency` still sets the number yourself. A core on an Apple silicon Mac is faster than a hosted runner's vCPU, so the same size usually finishes sooner here. ### Your network A job can't reach your Mac or your local network. If it needs something there, such as a package registry or a test database, add `--local-network`. The job still can't read your files. This block runs inside the VM, where a job that uses Docker could remove it. For a block no job can remove, run `relayrunner firewall on` once. It asks for your password, stays on after a restart, and `relayrunner firewall off` removes it. While it's on, `--local-network` has no effect. ### Run jobs on the Mac itself `--no-isolated` runs every job on the Mac, as you, with the tools you have installed. Jobs can read your files, so route them only from repos you trust. ```sh npx relayrunner connect --no-isolated ``` ### When something goes wrong `~/.relayrunner/isolated.log` has the details. It records the VM commands and their results, never a job's output or credentials, so it's safe to share. `connect` removes the images it downloaded for older runner versions, so they don't fill your disk. ## Remove a machine Remove it from the Runners page. You can remove your own machines; owners and admins can remove any. When someone leaves a workspace, their machines stay theirs and stop taking its jobs. ## Runners your org already has If you already run self-hosted runners, you can route jobs to them as they are, with no change on the runner's machine. On the **Runners** page, choose **Add runners from GitHub** and pick the ones to add. The list shows runners registered in your organization and runners registered on your private repos. Owners and admins can add them. A runner registered on a repo only takes that repo's jobs. The list checks up to 100 private repos. If you have more, type a repo's name in the dialog to look there. Added runners share the self-hosted step with your connected machines, and are picked the same way: online, idle, and with every label in the relay's `machine` input. Removing one from RelayRunner leaves it registered on GitHub. ## Public repos Machines never run a public repo's jobs. See [Principles](/docs/concepts/principles).