CLI Reference
bhatti is a single binary. bhatti serve runs the daemon; everything else is a CLI client that talks to the daemon’s HTTP API. All sandbox commands accept the sandbox name or ID interchangeably.
bhatti setup # configure endpoint + API keybhatti create --name dev # create a sandboxbhatti exec dev -- echo hello # run a commandbhatti shell dev # interactive shell (Ctrl+\ to detach)bhatti destroy dev # clean upOperations
Section titled “Operations”| Command | Syntax | Description |
|---|---|---|
| Core | ||
create | bhatti create [flags] | Create a new sandbox VM |
destroy | bhatti destroy <sandbox> [-y] | Destroy a sandbox (alias: rm) |
edit | bhatti edit <sandbox> [--keep-hot | --allow-cold] | Update mutable settings |
exec | bhatti exec <sandbox> [--] <command...> | Run a command in a sandbox |
inspect | bhatti inspect <sandbox> | Show sandbox details (alias: info) |
list | bhatti list [-o wide] | List sandboxes (alias: ls) |
ports | bhatti ports <sandbox> | List listening ports inside a sandbox |
ps | bhatti ps <sandbox> | List active sessions in a sandbox |
share | bhatti share <sandbox> [--revoke] | Generate a web shell URL |
shell | bhatti shell <sandbox> [--new] | Open an interactive shell (alias: sh) |
start | bhatti start <sandbox> [--force] | Resume a stopped sandbox |
stop | bhatti stop <sandbox> | Snapshot and stop a sandbox |
| Files | ||
file read | bhatti file read <sandbox> <path> | Read a file from a sandbox |
file write | bhatti file write <sandbox> <path> | Write a file (reads from stdin) |
file ls | bhatti file ls <sandbox> <path> | List directory contents |
| Networking | ||
publish | bhatti publish <sandbox> -p <port> [-a <alias>] [--shell] | Publish a port with a public URL |
unpublish | bhatti unpublish <sandbox> -p <port> | Remove a published port |
| Images | ||
image list | bhatti image list | List available rootfs images |
image pull | bhatti image pull <ref> [--name N] [--auth U:T] | Pull from a public OCI registry |
image import | bhatti image import <docker-ref> | --tar <path> [--name N] | Import a Docker image or tarball |
image save | bhatti image save <sandbox> --name <image> | Save a sandbox’s filesystem as an image |
image delete | bhatti image delete <name> [-y] | Delete an image |
image share | bhatti image share <name> --user <u>... | Share an image with specific users |
image unshare | bhatti image unshare <name> --user <u>... | Revoke image access from users |
| Volumes | ||
volume create | bhatti volume create --name <v> --size <MB> | Create a persistent volume |
volume list | bhatti volume list | List volumes |
volume delete | bhatti volume delete <name> [-y] | Delete a volume |
volume resize | bhatti volume resize <name> --size <MB> | Resize a volume (grow only) |
volume clone | bhatti volume clone <src> --name <new> | Clone a volume (point-in-time copy) |
volume backup | bhatti volume backup <name> | Back up a volume to S3 |
volume backup-list | bhatti volume backup-list <name> | List backups for a volume |
volume restore | bhatti volume restore <name> --backup-id <id> | Restore a volume from a backup |
volume backup-delete | bhatti volume backup-delete <name> <id> [-y] | Delete a volume backup |
| Secrets | ||
secret set | bhatti secret set <name> <value> | Create or update a secret |
secret list | bhatti secret list | List secret names |
secret delete | bhatti secret delete <name> [-y] | Delete a secret |
| Snapshots | ||
snapshot create | bhatti snapshot create <sandbox> --name <snap> | Checkpoint a running sandbox |
snapshot list | bhatti snapshot list | List snapshots |
snapshot resume | bhatti snapshot resume <snap> [--name <new>] | Resume from a snapshot into a new sandbox |
snapshot delete | bhatti snapshot delete <name> [-y] | Delete a snapshot |
| Server & admin | ||
serve | bhatti serve | Start the bhatti daemon |
setup | bhatti setup | Configure CLI endpoint and API key |
version | bhatti version | Print version and check for updates |
update | bhatti update [--cli-only] [--tiers <list>] | Update bhatti |
completion | bhatti completion <bash|zsh|fish> | Generate shell completion script |
user create | bhatti user create --name <u> [--max-...] | Create a user (server-only) |
user list | bhatti user list | List users (server-only) |
user rotate-key | bhatti user rotate-key <name> | Rotate a user’s API key (server-only) |
user delete | bhatti user delete <name> [-y] | Delete a user (server-only) |
admin status | bhatti admin status | One-shot system overview (server-only) |
admin events | bhatti admin events [--type T] [--since 24h] | Query the event log (server-only) |
admin metrics | bhatti admin metrics [--since 1h] | Query metrics snapshots (server-only) |
Global flags
Section titled “Global flags”These flags are accepted by every command.
| Flag | Description |
|---|---|
--url <url> | API endpoint (overrides config and BHATTI_URL). |
--token <key> | API key (overrides config and BHATTI_TOKEN). |
--data-dir <path> | Path to the server’s data directory. Required for bhatti user * and bhatti admin * since those operate directly on the local SQLite database. |
--json | Print machine-readable JSON instead of the default human format. Universally supported. |
--timing | Print a per-request timing breakdown (DNS, connect, TLS, server, transfer, total) to stderr after the command runs. |
-h, --help | Show help for any command. |
Environment variables
Section titled “Environment variables”| Variable | Used by | Description |
|---|---|---|
BHATTI_URL | CLI | API endpoint. Falls back when --url is not set and the config file has no api_url. |
BHATTI_TOKEN | CLI | API key. Same fallback semantics as BHATTI_URL. |
BHATTI_CONFIG | CLI + server | Override path to the config file. When set, layered loading is bypassed and only this file is read. |
BHATTI_LOG_LEVEL | server (bhatti serve) | debug, info (default), warn, error. |
BHATTI_FORCE_STREAM | CLI (bhatti exec) | Set to 1 to force NDJSON streaming output even when stdout is not a TTY. Useful in CI logs where you want real-time progress. |
Configuration precedence
Section titled “Configuration precedence”Per-call flag → config file → environment variable → built-in default.
--url <x> (highest)api_url: <x> (in config file)BHATTI_URL=<x> (env var)http://localhost:8080 (default, lowest)The config file is the primary source — bhatti setup writes it and most users never touch the rest. Environment variables are the fallback for CI pipelines and scripts.
See Configuration for the file format and layered loading rules (/etc/bhatti/config.yaml for system settings, ~/.bhatti/config.yaml for client credentials).
Output formats
Section titled “Output formats”Human (default). Compact, TTY-friendly. bhatti list prints columns; bhatti inspect prints kubectl-describe-style details with live disk usage on running VMs.
--json. Universally supported. Drops all human formatting; emits the raw API response (for queries) or a small status object (for mutations).
bhatti list -o wide. Adds CPUs, memory, disk, and image columns to list. Equivalent to kubectl get -o wide.
Streaming exec output. bhatti exec auto-detects how to format its output:
- Stdout is a TTY → NDJSON streaming, line-by-line, flushed immediately.
- Stdout is a pipe or
--jsonis set → buffered JSON with{exit_code, stdout, stderr}. - Override with
BHATTI_FORCE_STREAM=1to force streaming when piping.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | Success. |
1 | CLI or API error (see stderr for details and recovery hints). |
<n> | bhatti exec only — the child process’s exit code is forwarded verbatim, so a script’s $? reflects the command’s true status. |
Destructive commands (destroy, volume delete, image delete, snapshot delete, volume backup-delete, secret delete, user delete) require confirmation. Pass -y / --yes to skip the prompt; without -y in a non-interactive shell, the command exits 1.
Shell completion
Section titled “Shell completion”bhatti completion bash > /etc/bash_completion.d/bhattibhatti completion zsh > "${fpath[1]}/_bhatti"bhatti completion fish > ~/.config/fish/completions/bhatti.fishSandbox-name completion uses a local cache (/tmp/bhatti-completions-<uid>) updated by create, destroy, and list. It never hits the network — instant, works offline.