Skip to content

Adding Hosts

The hub holds no Docker socket of its own. Every machine that runs runner containers — including the one next to the hub — runs an agent that dials home over an authenticated WebSocket. The agent connects out, so there’s no inbound port to open, no SSH key, no VPN, and it works behind NAT. To grow your fleet, enroll more hosts.

  1. Start the enrollment.

    On the hosts page, choose Add host and give it a name like builder-01.

  2. Optionally request the isolated runtime.

    Tick Install sysbox-runc on this host in the same dialog to run isolated runners on it; the installer sets it up alongside the agent. See Isolated runtime.

  3. Copy the install command.

    The hub shows a one-time enrollment token baked into a single line:

    Terminal window
    curl -fsSL <hub>/install/<token>.sh | sudo bash
  4. Run it on the host machine.

    The installer auto-detects the package manager (apt or dnf) and architecture (amd64 or arm64), installs sysbox-runc if requested, pulls the public agent image (anonymous — no docker login), and runs it with the agent data volume, the Docker socket, and a read-only /:/host:ro bind mount for the host disk gauge.

  5. Wait for it to connect.

    The agent dials the hub, the enrollment token is consumed and swapped for a long-lived agent token, and the host appears online within a few seconds.

A new host adds capacity, but the hub won’t place runners there until a workload targets it. Open the workload, choose Edit hosts, check the new host, and save.

The reconciler distributes runners across every targeted host, respecting each workload’s per-host cap and the host’s shared capacity budget below.

Each host has an optional max runners budget, set on its detail page. Leave it unset for no cap. The budget is shared by all workloads scheduled on that host — it’s how you stop several workloads from over-provisioning one machine.

When several workloads target a host, the scheduler:

  1. Honors each workload’s minRunners floor first.
  2. Splits the host’s remaining budget across them in proportion to demand.

The Overview shows running runners against the host budget, not the sum of every workload’s maxRunners — so the number you read is the real ceiling for that machine.

To have the hub own zero compute and run runners only on remote machines, leave RUNAWAY_LOCAL_AGENT_TOKEN unset when you deploy the hub. The hub then enrolls only the remote agents you add — the shape a public Coolify deploy uses.

When an agent reconnects, the hub re-scans that host’s Docker reality and rebuilds its runner records from what’s actually there. That scan runs under the reconciler’s lock, so an agent reconnecting repeatedly can’t produce duplicate records or phantom spawns.

Per-host backoff means one misbehaving host doesn’t stall reconciliation of the others. A failing host backs off on its own schedule (per workload, per host) while healthy hosts keep getting runners. Offline hosts are skipped, not redistributed onto.

If a host is gone for good, the hosts page offers a force-delete that discards its orphaned runner records along with the host row. Use it only when the agent is never coming back; for a temporary outage, wait for it to reconnect.

Mint a fresh installer URL for an existing host from its detail page without wiping volume state — how you re-run the installer to pick up a new option, such as adding the isolated runtime to a host that didn’t have it.

This holds only for the same hub. If you reinstalled the hub or it lost its database, the agent’s saved identity points at a hub that’s gone and re-running the installer won’t reconnect it — you have to wipe the data volume first. See A host won’t reconnect after the hub was reinstalled.