Requirements
Runtime
Section titled “Runtime”| Item | Version | What for |
|---|---|---|
| Node.js | ≥ 20 | Building and testing the packages. The repository’s engines field requires it. |
| Docker | any recent | Running the runner in a container. The image is node:22-alpine. |
| npm | 10+ | The repository’s workspaces. |
You don’t need Node installed to run the containerized runner: only to build the packages or develop connectors.
A control-plane on the other side
Section titled “A control-plane on the other side”The runner is the “hands” half. On its own it boots, enrolls, and waits: with no control-plane listening on the tunnel, it does nothing useful. Before installing, have these ready:
- The tunnel URL (
RUNNER_TUNNEL_URL), in production:wss://tunnel.rootpilot.sh:8443. - The enrollment URL (
RUNNER_ENROLL_URL), in production:https://app.rootpilot.sh. - A way to prove identity: a bootstrap token for your organization, or a cloud identity the control-plane recognizes. See Attestation.
Egress
Section titled “Egress”The runner needs egress, and only egress. No inbound ports.
Always:
tunnel.rootpilot.sh:8443(WSS + mTLS), the tunnel.app.rootpilot.sh:443(HTTPS), enrollment, at boot and on every certificate renewal.
Depending on which connectors you enable (only the ones you use):
| Connector | Egress host |
|---|---|
datadog |
api.datadoghq.com |
github |
api.github.com |
aws, kubernetes |
*.amazonaws.com, *.eks.amazonaws.com |
gcp |
*.googleapis.com |
amplitude |
amplitude.com |
slack |
slack.com |
cloudflare |
api.cloudflare.com |
azion |
api.azion.com |
vercel |
api.vercel.com |
checkly |
api.checklyhq.com |
grafana |
your datasource endpoints (Mimir, Loki, Tempo, stack) |
mongo, sonarqube, jira |
your own hosts, which you supply in configuration |
Sizing
Section titled “Sizing”This repository publishes no CPU or memory figures, because there is no versioned benchmark here, and inventing one would be worse than omitting it. What the construction does let us state:
- The process is a single-container Node process, with no worker pool.
- The SQLite cache is
:memory:by default, so memory grows with the volume of state learned during the session and resets on every boot. RUNNER_IDEMPOTENCY_MAX_ENTRIES(default2000) bounds the idempotency cache on purpose, so a long-lived runner doesn’t grow without a ceiling.
Start small, observe, adjust. The runner is cattle: resizing means bringing up another one.
Credentials for your sources
Section titled “Credentials for your sources”None are required to boot. Every connector is lazy, instantiated on first use, so a missing key
only makes those operations answer auth_error; everything else keeps working. The full list is in
Connector credentials.