preloop-runner on a Linux or macOS host, registers it with a GitHub repository, organization, or Preloop control plane, and starts it. You need a registration token and outbound HTTPS access to GitHub. Check platform support first.
Requirements
- Linux (x86_64 or arm64) or macOS (Apple Silicon or Intel).
giton the host. The runner uses it to fetch actions and check out code.- Docker, only for jobs that use
container:,services:, or Docker actions. - Outbound HTTPS to GitHub, including
api.github.comand*.actions.githubusercontent.com.configurealso downloads Node 20 and Node 24 fromnodejs.orgunless you pass--no-externals.
Install the binary
1
Run the installer
Fetch the installer at a release tag, read it, then run it with The installer checks the binary against the release’s SHA-256 file and puts it in
--runner. That installs only preloop-runner, with no control plane or VM tooling.~/.local/bin. Pass --prefix <dir> to install under <dir>/bin instead.2
Or download the binary
Each release publishes one binary per platform, with a
.sha256 file and a CycloneDX SBOM.preloop-runner --version.
Get a registration token
Create the token right before you configure the runner. In the repository or organization settings, open Actions → Runners → New self-hosted runner, or use the GitHub CLI:- Repository:
gh api --method POST /repos/OWNER/REPO/actions/runners/registration-token --jq .token - Organization:
gh api --method POST /orgs/ORG/actions/runners/registration-token --jq .token
Configure and run
1
Configure the runner
Run For an organization runner, use
configure from the directory the runner will live in. That directory is the runner root. It holds the runner’s configuration, _work/ for job workspaces, and externals/ for Node.--url https://github.com/ORG. configure registers the runner, downloads Node 20 and Node 24, and writes .runner, .credentials, and .credentials_rsaparams. Those files are readable only by the owner.2
Start the runner
3
Run it as a service (Linux)
Create
/etc/systemd/system/preloop-runner.service. This example expects the binary at /usr/local/bin/preloop-runner, so copy it there or change ExecStart.WorkingDirectory must be the runner root. Do not combine this unit with --once or --ephemeral. Restart=always starts the runner again after every exit.Single-job runners
A runner configured with--ephemeral exits after its first job. run --once does the same for any configured runner. Use either on hosts that you provision for one job.
Connect to a Preloop control plane
Pointconfigure at the control plane’s base URL. Use the control plane’s system token as --token, not a GitHub registration token. The control plane accepts only that credential for registration.
The control plane gives the runner the address of its runner service, built from its public URL (
PRELOOP_PUBLIC_URL on the control plane). Set that URL to an address the runner host can reach. See control plane configuration.Run in a container
The imageghcr.io/preloopdev/preloop-runner supports linux/amd64 and linux/arm64. Its entrypoint is preloop-runner and its default command is run, so the container does not configure itself. Keep the runner state in a volume, and pass --runner-root to each command.
git, curl, CA certificates, and the Docker CLI with buildx. Container jobs need a Docker daemon that the container can reach.
Remove the runner
Deregister the runner with a remove token, not a registration token:remove deregisters the runner and deletes .runner, .credentials, and .credentials_rsaparams. It leaves _work/ and externals/ in place, so delete those yourself. If the server cannot deregister the runner, remove warns and deletes the local files anyway; remove the runner in the repository or organization runner settings to clear the leftover registration.
