RunnerYard

Open source / MIT

Ephemeral GitHub runners on your cloud.

Start one isolated worker per job, enforce a runtime budget, and remove the worker when the job ends.

No Kubernetes. No hosted control plane. The first adapter runs on Fly Machines; the compute interface stays provider-neutral.

One job lifecycleYour cloud account

GitHub Actions

Job assignment and status

RunnerYard controller

trusted

GitHub App, provider token, runtime ledger

Ephemeral worker

untrusted

One JIT config, one job, then destroyed

idle workers: 0worker secrets: 0

One machine for one job.

GitHub keeps the workflow experience. Your account supplies disposable compute.

01

GitHub assigns a job

The controller listens to one runner scale set. It never needs your repository code.

02

A clean worker starts

Your provider receives a short-lived lease and one GitHub JIT configuration.

03

The workflow runs once

The worker executes the job with the image, CPU, and memory you selected.

04

The worker is removed

Completion, timeout, or reconciliation destroys it. Idle workers default to zero.

Security model

Job code stays outside the control plane.

Workers are treated as hostile and disposable. Permanent credentials never enter the job environment.

Read every trust boundary

Credentials stay in control

GitHub App and provider credentials live only in the trusted controller. A worker gets one JIT configuration.

Workers stay separate

Control and worker scopes use separate apps and networks. The doctor command rejects shared Fly apps and worker secrets.

Compute is bounded first

Concurrency, maximum lifetime, and a durable rolling runtime budget are checked before a worker can start.

Cleanup owns only its fleet

Controller and lease metadata let reconciliation ignore infrastructure created by another controller.

Compute stops at your limit.

The controller reserves worst-case runtime before launch. Missing or corrupt budget state queues jobs instead of resetting the ceiling.

MIN_RUNNERS=0
MAX_RUNNERS=4
RUNNER_MAX_LIFETIME=2h
RUNNER_USAGE_BUDGET=166h40m

Scaffold it in one command.

The initializer writes local configuration and a canary workflow. It does not create infrastructure or upload credentials.

$ npx runneryard init --github https://github.com/acme/widgets
  1. 01

    Review the files

    Nothing is deployed by init.

  2. 02

    Create isolated apps

    Then run doctor before deploy.

  3. 03

    Run one canary

    Verify the worker disappears.

Bring the provider you trust.

The core depends on launch, inventory, and destroy. Provider details stay in adapters.

Fly Machines

Bundled now. Separate apps, networks, and zero-idle workers.

Other clouds

Implement the small compute contract without changing orchestration.

Read the adapter contract