Skip to content
View as Markdown

Workers and tunnels ​

A worker is a machine that runs sandboxes. It joins by dialing out, so it never needs an inbound port, a public address, or a firewall exception.

Joining ​

bash
# on the control plane: mint a join token for one workspace
curl -s -X POST "$API/portal/v1/join-tokens" \
  -H "X-Sandrpod-Token: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"worker-1"}'
json
{"secret":"jn_…","command":"docker run -d --name sandrpod-worker …"}

Run that command on the new machine. It starts poder with the token, which dials -api-url and registers.

FlagMeaning
-api-urlthe control plane to dial
-tokenthe join token (jn_…)
-regionwhich region this worker serves; must match what clients ask for
-networkDocker network for sandbox containers (default bridge)
-max-containershow many sandboxes this machine will hold

Region is the field that bites. The CLI and the E2B surface both default to local; a worker registered with -region=hk is invisible to them, and creation fails with no available local poder found while the fleet looks healthy.

What a worker advertises ​

At handshake the worker sends its identity, resources, capabilities, and tenant:

FieldEffect
X-Poder-Capabilities: egressonly this worker may host a sandbox that asks for an egress policy
X-Poder-Workspace: …placement scoped: a sandbox from workspace A is not scheduled onto workspace B's worker
resources (arch, OS, cores, memory)recorded on the sandbox so the API can report it

A sandbox that asks for a policy on a fleet with no capable worker gets 409, not a sandbox that silently runs unwalled.

Heartbeats and state ​

Workers heartbeat every ten seconds with their container list. That does three things: keeps the record ONLINE, lets the control plane reconcile sandbox states against the containers that actually exist, and (in a multi-instance deployment) renews which node holds the tunnel.

A worker that stops heartbeating goes OFFLINE; its sandboxes stop being reachable, and a create that lands on it fails with a reason rather than hanging.

Prerequisites on the machine ​

RequirementWhy
Docker socketthe worker creates containers
SANDRPOD_TOOLBOX_IMAGEthe sandbox base image, pulled on first use
ghcr.io/sandrpod/egress-proxy pre-pulledonly for sandboxes with an egress policy; without it creation fails after the record is written
Ports: none inbound; outbound HTTPS + DNSthe worker dials the control plane and pulls images

Disk is the resource that fills first: images plus per-sandbox writable layers. A 4 vCPU / 8 GB / 100 GB machine carries several concurrent sandboxes; the default sandbox is 1 core and 1 GiB.

Pausing versus deleting ​

Stopping a sandbox pauses the container; it still occupies a container slot on the worker until it is deleted. A worker at its max-containers limit refuses new placement (no available poder found), which is a capacity answer, not a bug.

Seeing the fleet ​

bash
sandrpod-cli poder list          # id, state, provider, arch, region
curl -s "$API/api/v1/poders" -H "X-Sandrpod-Token: $TOKEN" | jq

poder delete <id> removes the record and drops the tunnel; --keep-vm leaves a cloud VM running for debugging.

Next ​

Apache 2.0 — your clouds, your machines, your rules.