# snowglobe > snowglobe is a Go CLI that turns a Docker image into a static website that runs it in the > browser: real Linux on a 64-bit ARM CPU emulated in WebAssembly (armless), restored from a > snapshot taken once the app was ready. The output is a folder of static files (GitHub Pages > works); no server runs the program. Guests must be arm64 Alpine images (FROM alpine, built for > arm64, or FROM arm64v8/alpine). Docker is the only requirement. Live demos: https://filipecabaco.github.io/snowglobe/ (Elixir IEx, PostgreSQL, Elixir + Postgres, Python + Rich, TypeScript + Zod, Go + Bubble Tea, Rust + clap, Java + Gson, curl + jq, Supabase). Source and README: https://github.com/filipecabaco/snowglobe ## Commands - `snowglobe build [flags]` builds the site into `--out` (default `dist`). - `snowglobe serve [dir] [--port N]` previews a built site on localhost. - `snowglobe pool ` makes every site under a directory share one content-addressed blob store. - `snowglobe pwa [--name N] [--short-name N]` makes a built site an installable Progressive Web App: manifest, icons, and a service worker that keeps it working offline once it has run. Run it after `pool`. Every demo on the live site is installable. - `snowglobe pack [-o site.tar.gz]` writes a site as one self-contained tarball (.tar.gz or .tar.zst, pooled blobs included) to publish on a CDN. - `snowglobe run [site] [--name N] [--detach]` restores a built site headlessly in a sandboxed container (unprivileged, read-only, memory-capped, offline unless built with a network). In a terminal it is an interactive session (ctrl-] quits); with stdin piped, each line is typed in as a command and the output printed as plain text. The site can be a directory, a tarball, a tarball URL, or a deployed site's URL (e.g. https://filipecabaco.github.io/snowglobe/python/): it is fetched into a local cache first and revalidated on later runs. `-p HOST:GUEST` (repeatable) forwards a host port to a guest port, bound to 127.0.0.1 unless given as IP:HOST:GUEST; it needs a site built with `--network fetch`. - `snowglobe exec ` types one command into a detached instance and prints only what it printed (plain text when piped): the way for scripts and agents to drive a REPL. - `snowglobe attach ` joins a detached instance (ctrl-] detaches); `snowglobe ps` lists them; `snowglobe stop ` throws one away. - `snowglobe version` ## Build flags (and the image labels they override) - `--cmd CMD`: the program to run (default: the image's ENTRYPOINT + CMD). Drops the image's ready and exercise labels. - `--ready TEXT` / `snowglobe.ready`: snapshot once this text appears on the console (default: after 5 s of quiet). - `--title TEXT` / `snowglobe.title`: the page title. - `--memory MB` / `snowglobe.memory`: guest RAM (default 512). - `--exercise CMD` (repeatable) / `snowglobe.exercise` (JSON array): commands typed after the snapshot; the files they read are preloaded. - `--warm REGEX` / `snowglobe.warm`: extra guest paths to preload. - `--network fetch` / `snowglobe.network`: give the guest a network (default `none`). - `--cpus N` / `snowglobe.cpus`: guest CPUs, 1 to 8 (default 1); each runs in a Web Worker. Example Dockerfile labels: LABEL snowglobe.title="My app" snowglobe.ready="iex(1)> " snowglobe.memory="640" \ snowglobe.network="fetch" snowglobe.exercise='["h Enum.map"]' ## Networking (`--network fetch`) Every request leaves as the visitor's own browser request; there is no proxy server. - HTTP (port 80): each request becomes a fetch(). - HTTPS (port 443): the machine terminates TLS 1.3 itself (armless's web relay) with a per-build CA that only the guest trusts, then the request is replayed with fetch("https://..."). - WebSockets (ws://, wss://): the guest's upgrade opens a browser WebSocket; messages pass through. - In `snowglobe run`, the same requests leave from the container (through HTTPS_PROXY/HTTP_PROXY if set); other TCP connections are made directly; private addresses are refused. - Limits: CORS applies (servers without it answer 502), no raw TCP or UDP. ## What a built site contains - `index.html`: the page that restores the snapshot (`?embed` hides the status strip). - `system/state.bin.zst`: the snapshot; `system/filesystem.json` + blobs: the root filesystem over 9p. - `system/warm.pack`: files preloaded in one request; `warm-report.json` explains what went in. - `run.json`: measured facts of the build; `transcript.json`: the exercise commands and their output.