preloop
Local GitHub Actions engine that runs workflows in microVMs
TLDR
SYNOPSIS
preloop command [options]
DESCRIPTION
preloop is the command-line client and control plane for Preloop, a local and self-hosted GitHub Actions engine. It accepts the same workflow YAML GitHub does (`${{ }}` expressions, matrix jobs, reusable workflows, concurrency groups, OIDC) and runs each job in a hardware-isolated microVM. Uncommitted and untracked files in the working tree are included in a local run (`.gitignore` still applies). `preloop run` starts the engine automatically when nothing is listening; preloop serve is the explicit foreground server.The CLI talks to an engine at PRELOOP_URL (default `http://127.0.0.1:9090`). It can also register the official `actions/runner` binary, or the companion preloop-runner binary, against that engine. A webhook watchdog reconciles GitHub deliveries with the GitHub API so check runs still update when GitHub's webhook path is down.The published CLI/server pair shares version 0.34.0. Most of the tree is MIT; preloop serve (the control plane crate `preloop-runner-server`) is FSL-1.1-MIT and converts to MIT two years after each release.
CONFIGURATION
~/.preloop/config.toml
Default config written by preloop init. Override the path with PRELOOP_CONFIG. init records `[golden] baseimage`; **serve** prepares that golden on first run. **PRELOOPRUNNERBASEIMAGE** overrides the recorded image~/.preloop/
Default PRELOOP_HOME: state, goldens, and per-user service data. A system service defaults to `/var/lib/preloop`
COMMANDS
init
First-run wizard: GitHub credentials, the golden image every job VM forks from, run mode, then a preflight check. In a terminal it prompts; otherwise it takes the same answers as flags and never waits. Writes `$PRELOOP_CONFIG` (default `~/.preloop/config.toml`). --probe prints a JSON capability report and exits. --auth is `app`, `pat`, or `none`. --golden is `official` (default, about 60 GB on disk), `oci`, `dockerfile`, or `file`. --mode is `foreground`, `service`, or `none`. Exit 2 is a missing or invalid flag, 3 is preflight, 4 is image resolve/build/pullserve
Run the control plane and microVM pool in the foreground. --listen overrides PRELOOP_LISTEN. --public-url is the externally reachable base URL. --store selects durable state (`sqlite://`path, a bare path, or `postgres://…`). GitHub App flags: --github-app-id, --github-app-key, --github-app-installation-id, --webhook-secret, --saverun [-f file] [--event event] [--job job]
Submit a workflow and stream events until it finishes. Bare filenames resolve inside `.github/workflows/`. Default event is push. --payload is a webhook JSON body. --base is the base ref for `pullrequest` / `mergegroup`. --secret NAME=VALUE is repeatable. --strict-secrets fails when the workflow reads a secret this engine has not stored. -d / --detach returns immediately. --push publishes the result to GitHub after the run; --create-pr opens a pull request (implies --push); --pr-draft defaults to true. Interactive terminals pause a failed SmolVM job so you can fix and retry; pipes, CI, and --detach never pauseplan [-f file] [--json]
Print the expanded job DAG (matrix fan-out and `needs:`) without running anythingstatus [run-id] [--json] [--limit n]
Table of recent runs, or one machine-readable status word when a run id is given. Default limit is 20logs [run-id] [--job job] [--step n] [-f]
Logs for a run (default: most recent). --step is 1-based among steps declared in the workflow and needs --job when the run has more than one job. -f / --follow tails one job and needs --job unless the run has a single jobcancel [run-id]
Cancel a run. Defaults to the most recent active runrerun [run-id] [--failed] [--job job]
Re-run a completed run. With no flags every job starts a new attempt. --failed resets failed and cancelled jobs plus their dependents. --job resets one job and its dependentssecret set [--value value] [--repo owner/repo] [--env name] NAME
Store a secret. Omit --value to read one line from stdin (hidden on a TTY). list never prints values. rm deletes a name at the same scopesetup github
Configure GitHub App or fine-grained PAT credentials. --via is `app` or `pat`doctor [--repo owner/name]
Verify the stored GitHub credentialserver install / server uninstall
Install or remove the control plane as a systemd or launchd service. --user uses per-user units. --dry-run prints the planshell [run-ref]
Open a shell in a preserved failed VM. Default is the last failed rundebug [session]
Attach to a job paused at a failed step. --verdict is `retry`, `continue`, or `abort`. --from / --from-start pick the retry step. --json prints the paused session and exitsdap run-id
Attach an interactive DAP client to a debugger-enabled run and inspect live `github`, `env`, `runner`, `job`, `steps`, and `secrets` scopespush
Publish a completed run's result to GitHub (commit, pull request, check runs)webhooks list | replay | health
Inspect, requeue, and health-check the durable webhook queue. Replay needs no GitHub call; retention is 30 daysupdate [--check] [--version tag]
Poll GitHub Releases and atomically replace the installed binaryversion
Print the installed Preloop version
ENVIRONMENT
PRELOOP_URL
Engine base URL (default `http://127.0.0.1:9090`)PRELOOP_CONFIG / PRELOOP_HOME
Config file and state directoryPRELOOP_LISTEN / PRELOOP_PUBLIC_URL
Bind address and public URL for serve (overridden by --listen / --public-url)PRELOOP_STORE_URL
Durable-state backend for servePRELOOP_GITHUB_PAT
Fine-grained PAT used by init / setup github when --token is omittedPRELOOP_RUNNER_BASE_IMAGE / PRELOOP_RUNNER_STORAGE_GB
Golden image override and VM disk size (default 80 GiB)
CAVEATS
The official GitHub runner golden is about 9 GB compressed and unpacks toward 50 GB; 80 GB free disk is recommended. First serve can take several minutes while that artifact is downloaded and the golden VM is created. On Apple Silicon, x86_64 goldens run through Rosetta 2; Docker actions inside those VMs currently fail. `preloop run` invents only the git-derivable parts of a webhook (changed files, default PR type `synchronize`, target branch); pass --payload when a workflow needs PR numbers, labels, or similar. Secrets listed by preflight come from this engine's store, never from GitHub. The control plane licence forbids offering it as a hosted CI service that competes with Preloop's own offering.
HISTORY
Preloop is developed at preloopdev/preloop. The CLI crate is preloop-cli; it embeds the control plane so preloop status reports one version for both. preloop-runner is a separate Rust binary that speaks the same `actions/runner` protocol.
SEE ALSO
preloop-runner(1), act(1), gh(1), git(1), docker(1)
