Skip to content

Quickstart

Runaway runs as a small Docker stack you drop on a Linux host: a hub (the orchestrator and web UI) and an agent (which drives your Docker daemon and runs the actual runner containers). This guide takes you from nothing to a runner picking up a job in about five minutes.

You’ll need:

  • A Linux host with Docker and the Compose plugin — a homelab box, a VPS, anything you control.
  • A GitHub organization or personal account whose Actions workflows you want to run.
  • A classic personal access token (PAT) with the repo and admin:org scopes. Fine-grained tokens and GitHub App auth aren’t supported yet.
  1. Get Runaway.

    The hub builds from source; only the agent ships as a prebuilt image. Clone the repository:

    Terminal window
    git clone https://github.com/<owner>/runaway.git
    cd runaway
  2. Generate the secrets.

    Runaway needs three secrets. Generate them straight into a .env file:

    Terminal window
    {
    echo "RUNAWAY_MASTER_KEY=$(openssl rand -base64 32)"
    echo "BETTER_AUTH_SECRET=$(openssl rand -base64 32)"
    echo "RUNAWAY_LOCAL_AGENT_TOKEN=$(openssl rand -base64 32)"
    } >> .env
    • RUNAWAY_MASTER_KEY encrypts your GitHub tokens at rest.
    • BETTER_AUTH_SECRET signs your login session.
    • RUNAWAY_LOCAL_AGENT_TOKEN lets the bundled agent enroll itself.
  3. Start the stack.

    Terminal window
    docker compose -f docker-compose.example.yml up -d

    This builds and starts the hub alongside a co-located agent that enrolls itself on first boot. Give it a few seconds to come up.

  4. Create your admin account.

    Open http://localhost:3000 and create the first account. Runaway is single-admin — once that account exists, signup closes.

  5. Connect a GitHub organization.

    In the UI, add your organization (or personal account) and paste the classic PAT. Runaway validates it live and stores it encrypted at rest.

  6. Create a scale set.

    A scale set is a pool of ephemeral runners. Pick the org, the runner image, and the pool size:

    • minRunners — the warm floor kept ready. Set it to 0 to scale to zero between jobs.
    • maxRunners — the ceiling Runaway scales up to under load.

    Save it, and the reconciler spawns the pool within seconds. You’ll see the runners come online in the dashboard.

  7. Run a workflow.

    Point a workflow at your self-hosted pool and push it to a repo in the connected org:

    jobs:
    build:
    runs-on: self-hosted
    steps:
    - run: echo "running on Runaway"

    A runner picks up the job, runs it once, and is destroyed on completion — a fresh container takes the next one.

A single hub now manages a pool of ephemeral runners on your own machine. Each runner is a one-shot container (AutoRemove: true), so nothing accumulates between jobs. When the queue is empty the pool can scale to zero; when work arrives it scales back up to maxRunners.

You have a working single-host setup. From here you can:

  • Add more hosts — run one agent on any other Docker machine and it dials out to the hub over an authenticated WebSocket. No inbound port, no SSH, no Tailscale.
  • Cut scaling latency with webhooks — opt in per organization for a faster demand signal than polling, with polling kept as the automatic fallback.
  • Reuse caches between runs — every scale set gets a persistent /cache volume. Point your package managers and browser binaries at it instead of round-tripping through GitHub’s Actions cache.
  • Isolate each runner — wrap runners in the sysbox runtime for github-hosted-style isolation, where every job gets a fresh inner Docker daemon.