GitHub ↗

Ephemeral EC2 runners

for GitHub Actions

A single Go binary that turns workflow_job webhooks into short-lived EC2 instances - on-demand or spot, per pool - and reaps them when the job ends. The queue, the scheduler, the state and the operator console all live in the binary.

# single binary# sqlite# ec2 + iam + pricing# spot-friendly# jit runners
Features

Everything in one binary

Webhook to instance
A workflow_job webhook binds to a project through the repo, picks a pool from the runs-on labels, and the orchestrator claims the job and launches an instance for it. No queue service, no lambda - one 5s tick over SQLite.
Projects, pools, launch templates
A project is a logical grouping with a concurrency ceiling and cascading tags. Each of its pools owns one materialized EC2 launch template: AMI, instance types, subnets, security groups, root volume, runtime cap, spot toggle.
On-demand or spot, per pool
CreateFleet over every instance-type x subnet combination, with cost, lowest-price, capacity or priority allocation. Capacity errors are backed off and retried; a bad AMI or a missing IAM role fails immediately.
JIT runner registration
GitHub App auth only. The instance bootstraps against the server, collects a single-use HMAC callback token, and gets a just-in-time ephemeral runner config that never touches disk. No long-lived runner tokens on the machine.
Reaped, and costed
Instances past their pool's max runtime are terminated and the job marked reaped. An at-launch USD/hour quote from the Pricing API rolls up into a per-job cost on completion, best-effort and never blocking a spawn.
One binary to run
Go and SQLite, with the Vue 3 console embedded. Local or OIDC sign-in, TLS in-process (self-signed, operator PEM or Let's Encrypt), structured logs, and an audit trail of everything the orchestrator did.