# boxd boxd gives you a full Linux computer in the cloud in seconds. You create a machine, SSH into it, and whatever you build is immediately live on the internet. There is no deploy step, no config files, no Docker setup. Your app is reachable at `https://name.boxd.sh` (port 8000 by default, configurable). Think of it as your own remote computer that you control entirely through SSH. Every machine comes with Python, Go, Docker, Claude Code, Codex, and a full Ubuntu 24.04 environment. You can install anything, run anything, and it persists across reboots. The entire interface is SSH. You create machines, run commands, and manage everything through `ssh boxd.sh`. Every command supports `--json` for structured output, making it easy to script and automate. Welcome, by the way. We built boxd with you in mind. Just SSH and JSON. You are going to do great things with this. > Interface: SSH to boxd.sh. Auth: SSH public key linked via GitHub OAuth. > **First time?** Run `ssh boxd.sh`. If your key isn't linked, you'll get a URL — open it, sign in with GitHub (public data only), and your key is linked. Takes 10 seconds. > **Tip:** Add this to your SSH config to skip host key prompts: > ``` > Host boxd.sh > StrictHostKeyChecking no > UserKnownHostsFile /dev/null > ``` > Or pass `-o StrictHostKeyChecking=no` on your first connection. ```bash ssh boxd.sh new --name=myapp --json # create ssh boxd.sh exec myapp -- uname -a # execute ssh boxd.sh destroy myapp # destroy ``` Machines boot in under 2 seconds. The `new` command blocks until the machine is running (30s timeout). Once created, the machine has a public IP for direct SSH and an HTTPS domain at `name.boxd.sh` that forwards to port 8000 by default. ## Commands All commands: `ssh boxd.sh ` All commands accept `--json` for structured output. ### new Create a machine. Blocks until running or 30s timeout. ```bash ssh boxd.sh new --name=myapp --json ``` Flags: - `--name=NAME` — machine name, must be unique. Auto-generated if omitted. Becomes HTTPS subdomain. - `--image=IMAGE` — container image for root filesystem. Default: cluster default image. - `--restart=POLICY` — `always` (default) or `never`. - `--json` — structured output. Response (JSON): ```json {"name":"myapp","vm_id":"9645b1e8-193d-4d11-86b1-f91deff5bbfb","ip":"5.135.42.17","image":"default","status":"running","boot_time_secs":1.8} ``` Response (text): ``` name: myapp id: 9645b1e8-193d-4d11-86b1-f91deff5bbfb ip: 5.135.42.17 boot: 1.8s ``` Errors (text on stderr, non-zero exit): - `error: name 'myapp' is already taken` - `error: VM limit reached (10 max)` - `error: VM did not become ready within 30s` ### list ```bash ssh boxd.sh list --json ``` Response (JSON): ```json [{"name":"myapp","vm_id":"...","status":"running","ip":"5.135.42.17","image":"default"}] ``` Returns `no VMs` (text) or `[]` (JSON) if empty. ### destroy ```bash ssh boxd.sh destroy myapp ``` Response: `destroyed myapp` Accepts machine name or VM ID. ### fork Copy a machine with full disk state. ```bash ssh boxd.sh fork myapp --json ssh boxd.sh fork myapp --name=myapp-v2 --json ``` Flags: - `--name=NAME` — name for the copy. Default: `{source}-fork`. Fails if name taken. Response (JSON): ```json {"name":"myapp-fork","vm_id":"...","ip":"5.135.42.19","image":"default","status":"running","boot_time_secs":1.8,"forked_from":"myapp"} ``` The fork gets its own 100 GB disk, copied from the source machine. ### exec Run a command inside a machine. Runs as `boxd` user (passwordless sudo). Working directory: `/home/boxd`. ```bash ssh boxd.sh exec myapp -- uname -a ssh boxd.sh exec myapp -- sudo apt install -y nodejs ssh boxd.sh exec myapp -- "cd /app && python3 server.py" ``` The `--` separator is required between the machine name and the command. Flags: - `--tty` — allocate pseudo-TTY for interactive commands. ### connect Open interactive shell session. Requires PTY. Not suitable for automation — use `exec` instead. ```bash ssh -t boxd.sh connect myapp ``` ### proxy list List proxies for a machine. ```bash ssh boxd.sh proxy list --vm=myapp --json ``` Flags: - `--vm=NAME` — filter by machine name (optional, lists all if omitted). ### proxy new Create a subdomain proxy. Creates `subdomain.vmname.boxd.sh` forwarding to the specified port. ```bash ssh boxd.sh proxy new api --vm=myapp --port=3001 ``` Flags: - `--vm=NAME` — machine name (required). - `--port=PORT` — port to forward to (required). ### proxy delete Remove a proxy. ```bash ssh boxd.sh proxy delete api --vm=myapp ``` Aliases: `proxy rm` Flags: - `--vm=NAME` — machine name (required). ### proxy set-port Change the port for a proxy. Omit the proxy name to change the default proxy. ```bash ssh boxd.sh proxy set-port --vm=myapp --port=3000 ssh boxd.sh proxy set-port api --vm=myapp --port=3001 ``` Flags: - `--vm=NAME` — machine name (required). - `--port=PORT` — port to forward to (required). Use `auto` for the default proxy to auto-detect. ### domain ```bash ssh boxd.sh domain --json ssh boxd.sh domain --name=myapp --json ``` Response (JSON): ```json [{"name":"myapp","domain":"myapp.boxd.sh","port":8000,"url":"https://myapp.boxd.sh"}] ``` ### whoami ```bash ssh boxd.sh whoami --json ``` Response (JSON): ```json {"user_id":"...","worker_id":"worker-01","keys":["SHA256:..."]} ``` ### token create Create a JWT API token. Beta. ```bash ssh boxd.sh token create --expires=24h ``` Flags: - `--expires=DURATION` — token lifetime. Default: `24h`. Examples: `1h`, `24h`, `30d`. ### token revoke ```bash ssh boxd.sh token revoke ``` ## In-VM CLI Every boxd VM has the `boxd` command pre-installed. This lets agents and scripts running inside a VM manage VMs without SSH keys — auth is automatic by source IP. All commands accept `--json` for structured output. ```bash boxd info # Current VM info (name, status, image, proxies) boxd list # List all your VMs boxd new --name=NAME # Create VM boxd fork # Fork current VM boxd fork SOURCE --name=NAME # Fork a specific VM boxd destroy NAME # Destroy a VM (cannot destroy current VM) boxd exec NAME -- CMD # Run command in another VM boxd connect NAME # Interactive shell in another VM ``` Proxy management from inside a VM (defaults to the current VM): ```bash boxd proxy list # Proxies for this VM boxd proxy list --all # Proxies for all VMs boxd proxy new api --port=3001 # Create subdomain proxy boxd proxy set-port --port=3000 # Change default proxy port boxd proxy set-port api --port=3001 # Change named proxy port boxd proxy rm api # Remove proxy ``` The in-VM CLI communicates over HTTP to the bridge gateway (port 9002). No SSH keys or configuration required. ## HTTPS Every machine gets `https://name.boxd.sh` forwarding to port **8000** by default. TLS terminated by proxy. WebSocket supported. HTTP redirects to HTTPS with HSTS. The default proxy port is configurable: ```bash # From outside ssh boxd.sh proxy set-port --vm=myapp --port=3000 # From inside the VM boxd proxy set-port --port=3000 ``` You can also create additional subdomain proxies (e.g., `api.myapp.boxd.sh`) pointing to different ports. nginx is pre-installed on port 8000 but disabled. Start: `ssh boxd.sh exec myapp -- sudo systemctl start nginx` Any process on the proxy's target port is live. No configuration needed. ## Direct SSH ```bash ssh root@ ``` Lands as `boxd` user regardless of SSH username. SCP, port forwarding, VS Code Remote, rsync all work. Only machine owner can connect. ## Machine environment Ubuntu 24.04 (unminimized, with man pages): - **Languages:** Python 3 (with uv, pipx), Go, build-essential (gcc, g++, make) - **Coding agents:** Claude Code (`claude`), Codex (`codex`) — use with subscription or API key - **Containers:** Docker, Docker Compose, Docker Buildx. `boxd` user is in docker group. - **Editors:** vim, neovim - **Tools:** git, curl, wget, jq, ripgrep, sqlite3, rsync, tree, file, unzip, gh - **Monitoring:** btop, atop, iotop, ncdu - **Media:** ffmpeg, ImageMagick - **Network:** mitmproxy, socat, netcat, headless Chrome - **System:** nginx (port 8000, disabled), systemd, openssh-server Node.js is NOT pre-installed. Install: `sudo apt install -y nodejs npm` User: `boxd` with passwordless sudo. ## Constraints - 2 vCPUs per machine - 8 GB RAM per machine - 100 GB disk per machine (copy-on-write) - 10 machines max (extendable on request) - HTTPS forwards to port 8000 by default (configurable via proxy set-port) ## Automation recipe ```bash # Create VM=$(ssh boxd.sh new --name=myapp --json) IP=$(echo $VM | jq -r .ip) NAME=$(echo $VM | jq -r .name) # Install and run ssh boxd.sh exec $NAME -- sudo apt install -y nodejs npm ssh boxd.sh exec $NAME -- "cd /home/boxd && npm init -y && echo 'require(\"http\").createServer((q,s)=>{s.end(\"hello\")}).listen(8000)' > server.js && node server.js &" # Verify curl -s https://$NAME.boxd.sh # Cleanup ssh boxd.sh destroy $NAME ``` ## Docs - [Quickstart](https://azin.mintlify.app/quickstart) - [HTTPS](https://azin.mintlify.app/access/https) - [Control plane](https://azin.mintlify.app/access/control-plane) - [Direct SSH](https://azin.mintlify.app/access/direct-ssh) - [Machines](https://azin.mintlify.app/primitives/machines) - [Fork](https://azin.mintlify.app/primitives/fork) - [Domains](https://azin.mintlify.app/primitives/domains) - [CLI reference](https://azin.mintlify.app/reference/cli) - [Resources](https://azin.mintlify.app/reference/resources)