OpenComputer sandboxes are full Linux VMs, which means you can run a real Chromium browser inside them the same way you would on a laptop. This guide walks through the setup that makes it actually work: the right Chromium flavor, the system libraries you need, the OpenComputer-specific networking quirks, and how to persist browser state across runs. The examples use libretto, an AI-friendly CLI + library on top of Playwright. Everything here applies equally to raw Playwright, Puppeteer, browser-use, or Browserbase — libretto is just a convenient default.Documentation Index
Fetch the complete documentation index at: https://opensandbox-feat-cf-dev-cutover.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
GitHub Repository
Runnable reference implementation of everything in this guide.
libretto Docs
CLI + library reference for the browser-automation tool used in the examples.
When to reach for a browser (vs. an API)
- The target has no API (flight aggregators, airline sites, most SaaS admin UIs).
- The target needs a real logged-in session (cookies + localStorage + JS-challenge cookies).
- You want AI-driven interaction — describe a task in English, let the agent figure out the clicks.
- You need screenshots / visual artefacts for verification.
Step 1: Build a snapshot with Chromium pre-installed
Browser setup is heavy (apt packages + Chromium binary is ~500MB). Bake it into a named snapshot once, launch sandboxes from it in seconds.build-snapshot.ts
Step 2: Per-boot setup that can’t be baked in
A few things need to run at sandbox startup rather than during snapshot build, because they depend on per-sandbox state.launch.ts
Networking: the secretStore requirement
OpenComputer routes all outbound traffic through a secrets-injection proxy. The proxy only accepts traffic from sandboxes that have at least one sealed secret registered, because session registration happens as part of sealing secrets.
The workaround is to create a SecretStore with a wildcard egress allowlist and at least one (possibly dummy) entry:
opensandbox-proxy.crt we trusted earlier lets Chromium validate the MITM-rewritten certs.
Step 3: Run a headless browser
With the snapshot and per-boot setup in place, driving the browser is a normal libretto session:snapshot command requires an ANTHROPIC_API_KEY (or an OpenAI / Gemini / Vertex key — configure via .libretto/config.json). It’s the AI-driven feature that makes libretto different from raw Playwright.
Step 4: Run a headed browser (for interactive login)
For workflows where the user needs to log in themselves, you can render the browser to a virtual display and expose it via VNC. This lets you embed the running browser in a web UI. Install the VNC stack at runtime (same no-rebuild pattern as per-boot setup):DISPLAY=:99 in the sandbox envs when you create it, then open with --headed:
sandbox.getPreviewDomain(6080) and embed <iframe src="https://<id>-p6080.<domain>/vnc.html?autoconnect=true"> in your UI. Users click/type directly in the real browser.
Step 5: Persist login across runs
After the user logs in, save the auth state:Resource and concurrency limits
- Memory per VM — default is ~1GB. Each headless Chromium uses ~300-500MB; headed full Chromium uses ~500-800MB. Pass
memoryMB: 16384toSandbox.createfor browser-heavy work. - File descriptors — the default
nofilelimit of 1024 is too low for Chromium (which opens hundreds of FDs). Launch the server process undersudo bash -c "ulimit -n 65535 && exec ..."to raise it. - Concurrency — with default memory, run 2-3 browsers concurrently per sandbox. With 16GB and proper limits, 5+ works cleanly.
Choosing a browser automation library
| Library | Best for | OC integration |
|---|---|---|
| Playwright (direct) | Scripted automation with known selectors | No special setup beyond this guide |
| libretto | AI-agent-driven snapshots + interactive workflows | Shown above |
| browser-use | End-to-end natural-language agents | Install via pip install browser-use; set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH |
| Browserbase | Production-grade bot-detection bypass | Use libretto with --provider browserbase + API key |
Troubleshooting
407 from proxy after CONNECT
Your sandbox isn’t registered with the secrets proxy. Attach a secretStore with at least one secret entry.
Chromium exits with status 1 on launch
Missing shared library. Check .libretto/sessions/<name>/logs.jsonl for the specific .so missing. Add it to CHROMIUM_DEPS in the snapshot or install at runtime.
net::ERR_CERT_AUTHORITY_INVALID
Chromium doesn’t trust OC’s egress-proxy CA. Run the certutil NSS-import step from “Per-boot setup”.
ENOTFOUND localhost
The guest’s /etc/hosts is missing the localhost entry. Run the grep … /etc/hosts step from “Per-boot setup”.
EAGAIN / uv_thread_create / Killed
Out of memory or leaked browser processes from prior runs. Reap stale Chromium processes between sessions (pkill -9 -f chrome-headless-shell) and reduce MAX_CONCURRENT_BROWSERS.
Preview URL shows “Waiting for server”
Your server is bound to 127.0.0.1 instead of 0.0.0.0. OC’s edge forwards from the worker interface, not loopback. Set hostname: "0.0.0.0" when calling your web server’s listen().
SSE / streaming responses return 502
OC’s preview-URL edge buffers response bodies — streaming chunks don’t reach the client. Use short-polling (POST /api/job → GET /api/job/:id) instead of SSE or WebSockets for progress updates. WebSockets (for VNC, etc.) do pass through as upgrade connections; buffering only affects regular HTTP responses.
Next steps
- Read the libretto docs for the full CLI + library reference.
- See Snapshots for how to checkpoint a warmed-up browser VM.
- See Secret Stores for scoping egress and sealing real credentials.