Quick start
Beachball needs three things: a scheduler, at least one host, and a client. Each step below is one command, and every value it needs has a default.
1. Start a scheduler
The scheduler runs on celld. Its only required setting is
BEACHBALL_SECRET, a random value of at least 32 characters; every other
secret derives from it.
For local development, from a checkout:
pnpm setup
pnpm devpnpm dev generates .dev/beachball/root.secret on first use, derives a
bootstrap credential into .dev/beachball/local.token, and writes a bb
profile that uses it. Run source .dev/beachball/environment.sh in each
terminal that runs bb. The scheduler listens on http://127.0.0.1:8787
and runs on celld dev, which keeps its state in scheduler/.celld/dev; no
Docker is needed. BEACHBALL_DEV_OBJECT_STORE=s3 runs a fleet node against a
Docker Compose object store instead, the way production runs.
Without a deployment manifest, the scheduler is a single-tenant deployment in
the default region with one default workload class. The bootstrap
credential is both the administrator and the default client. See
configuration to add tenants, classes, and limits.
2. Join a host
On the scheduler side, create a one-use join command for the new host:
bb --profile local-operator host enrollment-token create host-1Run this on the new host before 2026-09-26T17:30:00Z (the token works once):
sudo bb agent join 'http://127.0.0.1:8787#bbe1.aG9zdC0x.…'On the host (x86-64 Linux with KVM), run the printed command. bb agent join:
- reads the region, network prefix, connection verification keys, and image
settings from the scheduler's
/v1/.well-known/beachball; - detects CPU, memory, and disk capacity (minus a reserve for the host), the uplink interface, and a free WireGuard UDP port;
- enables the cgroup controllers and IPv4/IPv6 forwarding (persisted in
/etc/sysctl.d/90-beachball.conf), and adds accept rules for Beachball's interfaces when a host firewall such as Docker or ufw drops forwarded traffic;bb agent runrestores those rules after a reboot; - enrolls the host and runs every prerequisite check with a fix for each failure.
The host is active as soon as it joins; the scheduler places work on it after
its first healthy heartbeat. Start the agent with the command join prints:
sudo bb agent runEvery detected value can be overridden; see bb agent setup --help.
3. Run a command
bb run ubuntu:26.04 -- uname -abb run creates an allocation, waits until the microVM is ready, and runs the
command. The image is any container image reference (alpine:3.20,
ghcr.io/org/app@sha256:…): the host pulls it and builds a bootable image the
first time it sees it, which takes a minute, and reuses the build afterwards.
Hosts build container images when they joined with --oci-kernel VMLINUX; a
signed Beachball image reference (name@sha256:<digest>) works on every host.
When the workload class has a default image, bb run -- uname -a is enough.
Choose resources per request:
bb run --cpu-millis 2000 --memory-mib 4096 --script ./job.shRelease the allocation when you are done:
bb allocation release ALLOCATION_IDFor a complete local Firecracker setup, including building and signing an
Ubuntu image, run pnpm setup:firecracker; see
run Beachball with Firecracker.