| 1 | # cloudflare-microvm-shell |
| 2 | |
| 3 | A browser terminal that executes shell commands on an **AWS Lambda MicroVM**, |
| 4 | wired **Cloudflare Worker → Durable Object → MicroVM**, with command output |
| 5 | streamed back to the browser as it is produced. |
| 6 | |
| 7 | ``` |
| 8 | browser terminal ──ws──▶ Worker ──▶ Durable Object ──https /exec──▶ MicroVM |
| 9 | (SPA) (routes) (session state) (streams) (runs sh) |
| 10 | ``` |
| 11 | |
| 12 | - **Worker** (`src/worker.ts`) serves the terminal SPA, binds the MicroVM |
| 13 | control plane (`RunMicrovm` / `GetMicrovm` / `CreateAuthToken`), and on each |
| 14 | WebSocket upgrade provisions the session's VM and hands its endpoint + auth |
| 15 | token to the Durable Object. |
| 16 | - **Durable Object** (`src/shell-session.ts`) owns one terminal session: it |
| 17 | keeps the VM coordinates in storage (so the VM is reused across commands, not |
| 18 | re-booted), POSTs each command to the VM's streaming `/exec` route, and |
| 19 | forwards stdout/stderr to the browser chunk-by-chunk. |
| 20 | - **MicroVM** (`src/shell-image.ts`) is an **effectful image**: the module is |
| 21 | both the image declaration and the in-VM server. The bundled Effect program |
| 22 | spawns `sh -c <command>` (scoped `ChildProcessSpawner`) and streams its |
| 23 | interleaved stdout/stderr, ending with an `__EXIT__:<code>` trailer. |
| 24 | |
| 25 | ## Run it in dev |
| 26 | |
| 27 | ```sh |
| 28 | bun alchemy dev |
| 29 | ``` |
| 30 | |
| 31 | Open the printed `http://localhost:…` URL, type a command (`echo hello`, |
| 32 | `uname -a`, `ls -la /`) and press enter. Under `alchemy dev` the Worker and |
| 33 | Durable Object run in local workerd while the MicroVM runs on the Floci |
| 34 | emulator — the cross-cloud STS assume-role and the VM's TLS data plane are |
| 35 | wired automatically (the emulator CA is trusted via `NODE_EXTRA_CA_CERTS`). |
| 36 | |
| 37 | To exit the first-apply smoke check without keeping the session alive: |
| 38 | |
| 39 | ```sh |
| 40 | ALCHEMY_DEV_ONCE=1 bun alchemy dev |
| 41 | ``` |
| 42 | |
| 43 | ## Deploy it live |
| 44 | |
| 45 | ```sh |
| 46 | bun alchemy deploy |
| 47 | ``` |
| 48 | |
| 49 | A live deploy requires the **AWS Lambda MicroVM preview entitlement** on the |
| 50 | account (the control-plane APIs are gated). Everything else — the Worker, the |
| 51 | Durable Object, the cross-cloud IAM User + assume-role Role — is standard. |