Quickstart
This is the path I recommend for everyone except remote-CLI users sharing someone else’s bhatti server. You’ll install the daemon on a Linux box you own, and from that same box you’ll create your first sandbox and run something inside it.
If you don’t have a Linux box with KVM in front of you, the Self-hosting page covers what you need (a Raspberry Pi 5, a Hetzner AX, or any cloud VM with nested virtualization is enough).
Install
Section titled “Install”curl -fsSL bhatti.sh/install | sudo bashThat’s the whole install. The script:
- Downloads
bhatti,lohar, Firecracker, the kernel, and the minimal Ubuntu 24.04 rootfs (~200 MB total). - Sets up the systemd service and starts the daemon.
- Creates an
adminuser and writes its API key + endpoint to your user’s~/.bhatti/config.yaml. You don’t need to runbhatti setupafter. The CLI on this box is already wired up.
The transcript ends with the admin API key printed once. Save it somewhere — you’ll want it later for adding teammates or driving the server from a different machine.
Create a sandbox
Section titled “Create a sandbox”bhatti create --name devsandbox/dev created (1 vCPU, 1024 MB) IP: 10.0.1.42 Shell: bhatti shell devDefaults are 1 vCPU and 1024 MB. Override with --cpus and
--memory. See bhatti create
for every flag.
Run a command
Section titled “Run a command”bhatti exec dev -- echo hello# → helloAnything after -- runs verbatim inside the sandbox. The -- is
optional when there’s no ambiguity:
bhatti exec dev uname -aOpen a shell
Section titled “Open a shell”bhatti shell devInteractive PTY, full keyboard. Press Ctrl+\ to detach — the shell
keeps running. Reconnect with bhatti shell dev and the scrollback
is replayed.
Publish a port
Section titled “Publish a port”If you want to reach a service running inside the sandbox from the internet:
bhatti exec dev -- bash -c 'python3 -m http.server 3000 &'bhatti publish dev -p 3000 -a my-app# → https://my-app.bhatti.shThat URL is public. The sandbox can be cold and the URL still works — the first request wakes it (~42 ms p50 on Hetzner). See Preview URLs for aliases, custom domains, and auth.
Clean up
Section titled “Clean up”bhatti destroy devOr bhatti destroy dev -y if you don’t want the confirmation prompt.
What just happened
Section titled “What just happened”bhatti createasked the daemon to boot a Firecracker microVM — a Linux VM with its own kernel, filesystem, and network interface.bhatti execsent a command over the wire protocol to lohar, the guest agent running as PID 1 inside the VM.bhatti shellopened a WebSocket and attached to a PTY session.bhatti destroystopped the VM and cleaned up the rootfs, TAP device, and IP.
The sandbox was a full Linux environment, not a container. When idle, it would have paused itself automatically and resumed on the next request in milliseconds.
Next steps
Section titled “Next steps”- Concepts — sandboxes, thermal states, the two binaries
- Self-hosting — adding teammates, custom domains, backups, the rest of the operator path
bhatti exec— streaming, timeouts, detachbhatti create— every flag
Driving a remote bhatti from your laptop
Section titled “Driving a remote bhatti from your laptop”If someone else runs the bhatti daemon and you only need the CLI on your local machine — or you want to install bhatti on a server and drive it from your laptop — install the CLI without sudo and point it at the server:
# Install the CLI binarycurl -fsSL bhatti.sh/install | bash
# Configure the endpoint and keybhatti setup --url https://your-server:8080 --token bht_abc...# or interactively:bhatti setupbhatti setup accepts --url and --token for non-interactive
configuration (agents, CI, provisioning scripts). Without flags, it
prompts. See bhatti setup for
the full reference.
The server operator gets your API key by running bhatti user create --name <you> once, on the server, and sending you the key. See
Self-hosting → adding teammates.