Runner machines
Windows, macOS and self-hosted jobs, on machines you register.
Some jobs cannot run on the cluster. A Windows container needs the NT kernel and cannot exist on a Linux host at all, and macOS does not containerise — so for windows-latest and macos-latest there is no pod anywhere. Register the machine instead, and the platform reaches it over SSH.
When you need one
runs-on | Where it runs |
|---|---|
ubuntu-latest, a container image | The cluster. Nothing to register. |
windows-latest | A registered Windows machine. |
macos-latest | A registered Mac. Apple's licence requires Apple hardware. |
self-hosted | A registered machine of any OS — that is what the label means. |
A job whose labels match no machine fails at once rather than running somewhere wrong, and its annotation says what is missing: no machine for that OS, a machine that is draining, or a label none has. The run fails rather than reporting success for work that was never built.
Registering a machine
Go to Settings → Platform → Runner machines and press Register machine. You declare what the machine is — address, the account CI will run as, its OS and architecture, and how many jobs it may take at once.
You are never asked for a private key. The platform generates an ed25519 pair, encrypts the private half at rest with the same cipher the secrets use, and shows you only the public half.
Installing the key
The screen gives you the command for that machine's OS, because the destination genuinely differs.
On Linux and macOS, the usual place:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'ssh-ed25519 AAAA… eqs-mac-mini-1' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysOn Windows, not that place. For any account in the Administrators group, OpenSSH reads one machine-wide file and ignores ~/.ssh/authorized_keys entirely:
Add-Content -Path "$env:ProgramData\ssh\administrators_authorized_keys" -Value 'ssh-ed25519 AAAA… eqs-win-runner-1' icacls "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
Permission denied (publickey) — a failure that reads like a bad key. Also make sure the file ends in a newline: a key appended to an unterminated last line joins the two into one invalid entry, and then nothing authenticates at all.Testing the connection
Test opens a session and asks the machine what it is. One round trip answers three questions: SSH works, a POSIX shell is there, and which machine this actually is.
A machine registered under the wrong OS fails the check and says so. That is not a connection problem and it is worse than one: the router would send windows-latest jobs to a Linux box, and each would fail on a command that is not there, with nothing pointing back at the registration.
When a check fails you get the reason verbatim — ssh: connect to host 10.0.0.42 port 22: Operation timed out — rather than a generic error. A machine that has never been reached says so, which is a different thing from unreachable.
What the machine needs
- An SSH server, and an unprivileged account for CI to run as.
- A POSIX shell. On Windows that means Git for Windows, with its
bash.exeset as the OpenSSHDefaultShell— every step runs through it. gitandtar, both of which Git for Windows ships.
Nothing else. The platform places the Node runtime that JavaScript actions need — built for that machine's own OS and architecture — the first time a job runs there.
Draining and removing
Drain finishes the jobs in flight and takes no new ones: the state to use before rebooting or updating a machine. Remove makes the platform forget it.
authorized_keys still carries the platform's public key until you take it out.Isolation is weaker than a container
Worth saying plainly. A job on a registered machine sees whatever the previous job left outside its workspace: the home directory, /tmp, installed packages, the state of any daemon. A container gives a fresh root each time and this does not.
What is mitigated: the account is unprivileged, the workspace is per job, and cleanup refuses any path outside the work root. Use a registered machine for work you would be comfortable running on a shared build box.