# How to run Selenium in a cloud sandbox Pip-install selenium in an Ubuntu 24.04 microVM and let Selenium Manager fetch Chrome and chromedriver, or run a Grid container there. **On Runtime, Selenium needs no browser setup of its own.** Selenium Manager, built into Selenium since 4.11, downloads Chrome for Testing and the matching chromedriver the first time a test asks for Chrome, and every sandbox is a Firecracker microVM with Python 3.12, Node.js 24 and `sudo` to receive them. Each test run gets a clean machine with no profile, cookies or downloads left by the last one, from $0.03125 an hour for 2 vCPU and 4 GiB while it waits ([pricing](/docs/pricing)). Selenium 4.49.0 was the current release on PyPI and npm on 25 September 2026. ## Two ways to use a sandbox | Where the test code runs | What runs in the sandbox | Use it when | | ------------------------ | ----------------------------------------- | ------------------------------------------------- | | In the sandbox | Python or Node, Selenium, Chrome | CI jobs, agents, anything that should run remote | | On your machine | A Selenium Grid container, reached by you | An existing suite that expects a `Remote` browser | ## Run a Selenium script in the sandbox ```ts check import { writeFile } from "node:fs/promises"; import { Sandbox } from "withruntime"; const test = ` import sys from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--headless=new") driver = webdriver.Chrome(options=options) driver.get(sys.argv[1]) driver.save_screenshot("home.png") print(driver.title) driver.quit() `; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 900 }); const slow = { check: true, timeoutMs: 600_000 } as const; await sbx.exec( "sudo apt-get update -qq && sudo apt-get install -y -qq fonts-liberation libasound2t64 " + "libatk-bridge2.0-0t64 libcups2t64 libgbm1 libgtk-3-0t64 libnss3 libxss1", slow, ); await sbx.exec("pip install --quiet selenium==4.49.0", slow); await sbx.files.write("/workspace/home.py", test); const run = await sbx.exec(["python3", "home.py", "https://example.com"], slow); console.log(run.stdout); await writeFile("home.png", await sbx.files.read("/workspace/home.png")); ``` ```python check from withruntime import Sandbox LIBS = ("fonts-liberation libasound2t64 libatk-bridge2.0-0t64 libcups2t64 " "libgbm1 libgtk-3-0t64 libnss3 libxss1") with Sandbox.create(disk_mib=8192, timeout_seconds=900) as sbx: sbx.exec(f"sudo apt-get update -qq && sudo apt-get install -y -qq {LIBS}", check=True, timeout_ms=600_000) sbx.exec("pip install --quiet selenium==4.49.0", check=True, timeout_ms=600_000) sbx.files.upload("home.py", "/workspace/home.py") # the script above run = sbx.exec(["python3", "home.py", "https://example.com"], check=True, timeout_ms=600_000) print(run.stdout) sbx.files.download("/workspace/home.png", "home.png") ``` The first `webdriver.Chrome()` takes longer than later ones: that is Selenium Manager downloading the browser and driver into `~/.cache/selenium`, which `SE_CACHE_PATH` moves. `pip install` needs no virtual environment; it installs to `/workspace/.local` ([the sandbox environment](/docs/sandbox-environment#who-you-are)). The library names are Ubuntu 24.04's (`t64` suffixes), checked on packages.ubuntu.com on 25 September 2026. For JavaScript, `npm install selenium-webdriver@4.49.0` uses the same Selenium Manager and the same libraries. ## Why not `apt-get install chromium-browser` On Ubuntu 24.04, `chromium-browser` (version `2:1snap1-0ubuntu2`) and `firefox` (`1:1snap1-0ubuntu5`) are transitional packages that install the Snap versions. Chrome for Testing, which Selenium Manager downloads, is a plain binary built for automation, so leave the browser to Selenium. ## Drive a browser in the sandbox from your own test suite Run Selenium's `standalone-chrome` image with [Docker in the sandbox](/how-to/run-docker-in-a-sandbox), forward its port 4444 to your machine, and point `webdriver.Remote` at it. Your tests stay where they are; only the browser moves. ```python check from selenium import webdriver from withruntime import Sandbox with Sandbox.create(disk_mib=10_240, timeout_seconds=3600) as sbx: sbx.exec("sudo enable-docker", check=True, timeout_ms=600_000) sbx.exec("docker run -d -p 4444:4444 -p 7900:7900 --shm-size=2g " "selenium/standalone-chrome:4.48.0-20260905", check=True, timeout_ms=900_000) sbx.exec("timeout 120 bash -c 'until curl -sf localhost:4444/status; do sleep 2; done'", check=True, timeout_ms=180_000) with sbx.forward_port(4444, local_port=0) as grid: driver = webdriver.Remote(command_executor=f"http://127.0.0.1:{grid.local_port}", options=webdriver.ChromeOptions()) driver.get("https://example.com") print(driver.title) driver.quit() ``` ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ diskMiB: 10_240, timeoutSeconds: 3600 }); await sbx.exec("sudo enable-docker", { check: true, timeoutMs: 600_000 }); await sbx.exec( "docker run -d -p 4444:4444 -p 7900:7900 --shm-size=2g selenium/standalone-chrome:4.48.0-20260905", { check: true, timeoutMs: 900_000 }, ); const grid = await sbx.forwardPort(4444, { localPort: 4444 }); const watch = await sbx.forwardPort(7900, { localPort: 7900 }); console.log("Grid: http://127.0.0.1:4444 live view: http://127.0.0.1:7900/?autoconnect=1"); // Run your suite against http://127.0.0.1:4444, then: await Promise.all([grid.close(), watch.close()]); ``` Port 7900 is the image's noVNC view of the browser; the project's README gives its default password as `secret`. The forward goes through Runtime's API with your key, so neither port is open to the internet ([forward ports](/docs/editors#forward-ports)). Docker Hub images come through `mirror.gcr.io` first. ## Limits worth knowing - **Disk.** Chrome for Testing plus its libraries fit in an 8 GiB disk; the Grid image with Docker needs more, and the free trial allows up to 10 GiB. - **Time.** A command's default timeout is 60 seconds. Give installs and whole suites `timeoutMs`, and the sandbox a `timeoutSeconds` longer than the run. - **Ports.** A trial sandbox reaches ports 80 and 443 only, which covers Selenium Manager's downloads and most sites under test. Paid sandboxes reach any port, such as a staging server on 8443. - **Parallel runs.** A paid account runs 100 sandboxes at once to start with; the trial runs eight. Split a suite by file across sandboxes and each shard gets its own browser. ## Related - [Playwright in a sandbox](/integrations/playwright) and [Puppeteer in a sandbox](/integrations/puppeteer) for the other two automation libraries. - [Preview agent-built apps](/use-cases/preview-agent-built-apps) to test an app that runs in the same sandbox. - [Agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench) for graded runs at scale. ## Sources - Selenium Manager, https://www.selenium.dev/documentation/selenium_manager/, read 25 September 2026 - Selenium Chrome options, https://www.selenium.dev/documentation/webdriver/browsers/chrome/, read 25 September 2026 - docker-selenium README, https://github.com/SeleniumHQ/docker-selenium, read 25 September 2026 - PyPI, https://pypi.org/project/selenium/, and npm, https://registry.npmjs.org/selenium-webdriver, read 25 September 2026 - Ubuntu 24.04 package pages, https://packages.ubuntu.com/noble/, read 25 September 2026 Facts on this page were checked on 25 September 2026.