1# cloudflare-microvm-shell
2
3A browser terminal that executes shell commands on an **AWS Lambda MicroVM**,
4wired **Cloudflare Worker → Durable Object → MicroVM**, with command output
5streamed back to the browser as it is produced.
6
7```
8browser 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
28bun alchemy dev
29```
30
31Open the printed `http://localhost:…` URL, type a command (`echo hello`,
32`uname -a`, `ls -la /`) and press enter. Under `alchemy dev` the Worker and
33Durable Object run in local workerd while the MicroVM runs on the Floci
34emulator — the cross-cloud STS assume-role and the VM's TLS data plane are
35wired automatically (the emulator CA is trusted via `NODE_EXTRA_CA_CERTS`).
36
37To exit the first-apply smoke check without keeping the session alive:
38
39```sh
40ALCHEMY_DEV_ONCE=1 bun alchemy dev
41```
42
43## Deploy it live
44
45```sh
46bun alchemy deploy
47```
48
49A live deploy requires the **AWS Lambda MicroVM preview entitlement** on the
50account (the control-plane APIs are gated). Everything else — the Worker, the
51Durable Object, the cross-cloud IAM User + assume-role Role — is standard.