Skip to content

Repository files navigation

Remote Browser Kit

A Docker-based remote browser platform for automation, testing, debugging, and browser infrastructure.

Run Chromium, Firefox, Edge, or WebKit in disposable Linux containers, driven over VNC and CDP — for Eggplant Functional, Playwright, Selenium, or just watching a browser run somewhere that isn't your laptop.

CI License: MIT

Replace OWNER/REPO in the badge URL above once this is pushed to GitHub.


Supported browsers

Engine BROWSER= Source Included by default?
Chromium chromium Debian package ✅ always
Firefox ESR firefox Debian package opt-in: INCLUDE_FIREFOX=true
Microsoft Edge edge Microsoft's apt repository opt-in: INCLUDE_EDGE=true
WebKit webkit Playwright's MiniBrowser opt-in: INCLUDE_WEBKIT=true

Key features

  • One command to scale, any enginebrowser.cmd start 10 firefox gets 10 isolated Firefox containers with sequential ports, no manual docker-compose.yml editing.
  • Disposable by default — fresh profile every container start; SESSION_MODE=persistent opts in to cookies/logins surviving a restart.
  • Real automation, not just visual checks — Chromium/Edge containers publish a CDP port; Playwright's connectOverCDP() or Selenium's debugger_address drive the exact browser you're watching over VNC.
  • Watchable two ways — a VNC port for Eggplant/any VNC client, plus a noVNC web portal for anyone with just a browser.
  • Deterministic rendering — fixed resolution, fixed zoom, first-run dialogs pre-suppressed, so reference images stay valid across runs.
  • Health-checked and resource-capped — Docker-native health checks per container, CPU/memory limits so one runaway instance can't starve the rest.

Architecture

flowchart LR
    CMD["browser.cmd\n(farm manager)"] -->|"docker run -e BROWSER=... x N"| C["Container rb-N\nXvfb + Openbox + <engine>\n+ x11vnc + noVNC"]
    EGG["Eggplant Functional /\nany VNC client"] -->|VNC 5900+N| C
    WEB["Any web browser"] -->|HTTP 6080+N| C
    AUTO["Playwright / Selenium"] -.->|"CDP 9200+N\n(chromium/edge only)"| C
Loading

Full breakdown of every layer and the design decisions behind them: docs/architecture.md. Per-engine capability matrix: docs/browsers.md.

Quick start (2 minutes)

git clone <this-repo-url> && cd "RemoteBrowser v2.0"
browser.cmd build              # builds Chromium (default engine), a few minutes the first time
browser.cmd start 1            # start one container
browser.cmd list                # get its VNC/noVNC connection details

Open http://localhost:6081/vnc.html in any browser to watch it, or point a VNC client (or Eggplant) at localhost:5901. Point Playwright at http://localhost:9201 (see Playwright) to drive it.

browser.cmd stop                # tear everything down when you're done

That's the whole loop. Everything past this point is reference material for when you need more than one container, a different engine, or persistence.

Screenshots

Not yet captured. This section is structured so real screenshots drop in without any doc changes — see assets/README.md for exactly what to capture and the expected filenames. No mock/fabricated images are included.


Why Remote Browser Kit

Image-based UI test tools compare screenshots pixel-for-pixel. A browser running directly on a tester's machine is a moving target — window size drifts, zoom changes, profile state piles up, and you can't run more than one at a time without them fighting over the screen. Cross-browser coverage makes it worse: Chromium, Firefox, Edge, and WebKit all render slightly differently, and getting a clean, isolated instance of each running side by side is its own infrastructure problem. Remote Browser Kit solves this by running one engine per disposable container, exposed purely as a VNC framebuffer at a fixed resolution — recycle a container for a byte-for-byte clean browser, run more containers for parallelism.

Remote Browser Kit Manual/local browser Headless-only automation Commercial cloud grid
Cost Free, self-hosted Free Free Paid, per-minute/seat
Watchable while automating ✅ VNC + noVNC ✅ it's right there ❌ invisible by design ⚠️ usually, via their own viewer
Disposable, reproducible state ✅ fresh profile every start ❌ profile drift over time ✅ (already stateless)
Multi-engine on one platform ✅ Chromium/Firefox/Edge/WebKit ⚠️ manual installs per engine ⚠️ depends on the framework
Runs on infrastructure you control ❌ vendor's cloud
Native VNC support (Eggplant, etc.) ⚠️ varies
Setup cost Docker + one script none some account + billing

Who this is for: QA/test engineers who need one-to-many disposable, cross-browser targets on a machine running Docker Desktop, and automation engineers who'd rather watch Playwright/Selenium drive a real container than debug a headless run blind.

Use cases

  • Playwright — attach connectOverCDP() to a running, watchable Chromium/Edge container instead of a headless instance you can't see.
  • Selenium — same CDP port, via debugger_address.
  • Eggplant Functional — every container is already a VNC SUT; browser.cmd list prints the connection table.
  • Manual/exploratory testing — open noVNC in any browser, no VNC client install required, click around like it's a normal desktop.
  • Remote debugging — reproduce a user-reported bug in a clean, disposable browser you (or a teammate) can watch live, without touching your own machine's browser state.
  • CIexamples/ci-pipeline.ps1 shows the build → start → wait-healthy → test → always-tear-down shape for a pipeline step.

Installation

Prerequisites

Tool Download
Docker Desktop (Windows) https://www.docker.com/products/docker-desktop
Git (optional, for cloning) https://git-scm.com/download/win

Make sure Docker Desktop is running (whale icon in the system tray) before continuing.

Folder structure

RemoteBrowser v2.0\
│
├── browser.cmd            ← the only file you run day to day
├── env                     ← the only file you edit day to day
├── docker-compose.yml      ← builds the image only, never used at runtime
├── Dockerfile              ← the container image recipe (Chromium always; Firefox/Edge/WebKit opt-in build args)
├── README.md
├── LICENSE
├── SECURITY.md
│
├── config\                 ← baked into the image at build time
│   ├── chromium-prefs.json    (shared by Chromium and Edge)
│   ├── firefox-prefs.js
│   ├── openbox-rc.xml
│   └── logrotate.conf
│
├── scripts\                 ← baked into the image at build time
│   ├── start.sh                (browser-agnostic orchestration)
│   ├── healthcheck.sh
│   └── browsers\                (one launcher per engine)
│       ├── chromium.sh
│       ├── firefox.sh
│       ├── edge.sh
│       └── webkit.sh
│
├── docs\                   ← architecture, browsers, usage, config, dev, security, troubleshooting, FAQ
├── examples\                ← per-browser quick starts, Eggplant, CI pipeline, Playwright/Selenium automation
├── tests\                   ← smoke test (per engine) + browser validation test
├── assets\                  ← real screenshots (once captured — see assets/README.md)
└── .github\                 ← CI workflow, issue/PR templates, release notes config

Build the image (once)

browser.cmd build

Builds Chromium only by default — a few minutes on the first build. To add Firefox, Edge, and/or WebKit, set the matching INCLUDE_FIREFOX / INCLUDE_EDGE / INCLUDE_WEBKIT flag(s) to true in env before building (each one adds real time and image size — see the build matrix in docs/browsers.md). Cached by default; re-run after changing Dockerfile, scripts/**, or config/*. Use browser.cmd build clean to force a from-scratch --no-cache rebuild.


Usage

browser.cmd build                    Build the image (cached)
browser.cmd build clean              Build from scratch (--no-cache)
browser.cmd start <N> [browser]      Start N containers (chromium|firefox|edge|webkit)
browser.cmd stop                     Stop and remove all containers
browser.cmd restart <N> [browser]    Stop all, then start N fresh ones
browser.cmd status                   Show running containers with ports
browser.cmd list                     Show Eggplant SUT connection table
browser.cmd logs <N>                 See live logs for container N
browser.cmd shell <N>                Open a terminal inside container N
browser.cmd health                   Check health of all containers

Port rule: 5900 + N for VNC, 6080 + N for noVNC, 9200 + N for the CDP automation port (Chromium/Edge only). rb-15901/6081/9201. browser.cmd list always shows the VNC/noVNC table.

Full walkthrough (multi-instance farms, watching a container, resetting mid test-run, persistent sessions): docs/usage.md.

Never run docker compose up — that only builds the image, it doesn't set the ports/mounts/env that browser.cmd does. Always use browser.cmd.

Build options

browser.cmd build installs Chromium only by default. Enable additional engines by setting flags in env before building:

Combination env settings
Chromium only (default) (nothing to set)
Chromium + Firefox INCLUDE_FIREFOX=true
Chromium + Edge INCLUDE_EDGE=true
Chromium + WebKit INCLUDE_WEBKIT=true
All four browsers all three flags true

Full build matrix with equivalent raw docker build --build-arg commands: docs/browsers.md.

Browser selection

BROWSER picks which of the installed engines a container runs. Set it in env for a farm-wide default, or override per batch:

browser.cmd start 5                  # 5 containers, using env's BROWSER (default: chromium)
browser.cmd start 3 firefox          # 3 Firefox containers, this batch only (needs INCLUDE_FIREFOX=true at build time)
browser.cmd start 2 edge
browser.cmd start 1 webkit

Rejected client-side by browser.cmd and again inside the container by scripts/start.sh — both if the value isn't one of the four known engines, and if it wasn't actually built into the image (clear error either way, telling you which build flag to flip). Full capability matrix (what each engine does and doesn't support — kiosk mode, zoom, CDP automation): docs/browsers.md.

Persistent sessions

# in env:
SESSION_MODE=persistent

Each container's profile is bind-mounted at profiles/rb-N/<browser>/ on the host, namespaced per engine so switching BROWSER on the same instance number never mixes profiles. Default (fresh) wipes the profile on every container start. Details: docs/usage.md.

Remote access

Every container publishes VNC (5900+N) and a noVNC web portal (6080+N), bound to 127.0.0.1 on the host by default — see docs/security.md before widening that.

Connecting from Eggplant Functional

Field Value
Type VNC
Host localhost
Port 5900 + N (5901 for rb-1, 5902 for rb-2, …)
Password whatever VNC_PASS is set to in env

Full worked example: examples/eggplant-sut.md.

Automation integration

Playwright

Chromium and Edge containers publish a CDP port (9200+N); Playwright can connectOverCDP() to the exact browser you're watching over VNC instead of launching its own headless instance. Firefox/WebKit aren't supported this way — see why in the example. Full walkthrough with runnable Node.js and Python code: examples/playwright-automation.md.

Selenium

Same CDP port, via Selenium 4's debugger_address option (Chromium/Edge only). Full walkthrough: examples/selenium-automation.md.

Examples

Configuration

Day-to-day settings live in envbrowser.cmd loads it automatically and it overrides the script's built-in defaults:

BROWSER=chromium
START_URL=https://your-app-url.com/
VNC_PASS=your-password-here
BROWSER_MODE=normal
SCREEN_WIDTH=1920
SCREEN_HEIGHT=1080
SESSION_MODE=fresh

Keep BROWSER_ZOOM=1.0 and the resolution at 1920x1080 (or whatever you captured reference images at) — changing either after capturing Eggplant images breaks image matching.

Full variable reference, per-engine flag rationale, and security notes: docs/configuration.md.

Development setup

Nothing to compile — this is a Dockerfile, browser launcher scripts, a startup/healthcheck script, one batch script, and static config. See docs/development.md for the local iteration loop, linting, and what does/doesn't require a rebuild.

Testing

bash tests/smoke-test.sh              # chromium (default)
bash tests/smoke-test.sh firefox
bash tests/browser-validation.sh      # confirms bad BROWSER values are rejected

Builds the image if needed, boots a throwaway container for the given engine, waits for it to report healthy, confirms noVNC/VNC respond and the right browser process is running, tears it down. Testing an engine other than chromium requires an image built with the matching INCLUDE_* flag (see Build options). CI builds once with every flag enabled and runs the smoke test as a 4-way matrix on every push. There's no application code to unit test — see tests/README.md for what is and isn't covered.

Security

This is a tool for disposable browsers on a machine you control, not a hardened multi-tenant service — the defaults reflect that. In short: ports are bound to 127.0.0.1 only by default, VNC_PASS=changeme is a placeholder you must change before wider exposure, real secrets belong in an untracked .env/.env.local override rather than the committed env template, and third-party package sources (Microsoft's apt repo for Edge, Playwright's CDN for WebKit) are pinned by key/checksum rather than trusted blindly. Vulnerability reporting process: SECURITY.md. Full operational security picture, including container isolation and credential-handling guidance: docs/security.md.

Troubleshooting

Quick hits — full guide at docs/troubleshooting.md.

Symptom Check
"Connection refused" in Eggplant Used browser.cmd start, not docker compose up? Port is 5900+N, not 5900? browser.cmd status shows it running?
browser.cmd is not recognized Run it from inside the RemoteBrowser v2.0 folder.
Black screen over VNC browser.cmd logs <N> — look for [ERROR]/[HEALTH] FAIL lines.
browser.cmd build fails on Edge/WebKit layers Check outbound access to packages.microsoft.com and Playwright's browser CDN — see docs/troubleshooting.md.
Kiosk/fullscreen/zoom "doesn't work" Check the capability matrix in docs/browsers.md — not every engine supports every mode.

How much RAM do I need?

Browsers Minimum RAM
1 2 GB
5 6 GB
10 10 GB
20 18 GB

Roadmap

  • Native per-instance START_URL override within a single browser.cmd start batch (today: manual docker run, see examples/custom-single-container.md)
  • Linux/macOS-native control script (today: browser.cmd is Windows-batch-only; the container itself is already cross-platform)
  • WebDriver/Marionette automation support for the Firefox container (today: CDP automation is Chromium/Edge-only — see docs/browsers.md)
  • Optional non-loopback bind for teams running the farm on a shared host behind their own reverse proxy/VPN
  • Real screenshots/GIF in assets/ (structure is ready — see assets/README.md)

Contributing

  1. Read docs/architecture.md, docs/browsers.md, and docs/development.md first.
  2. Run bash tests/smoke-test.sh <browser> for whichever engine(s) your change affects (all four if it touches shared logic in start.sh), and bash tests/browser-validation.sh if you touched validation. If you touched scripts/*.sh or the Dockerfile, run ShellCheck/Hadolint locally (commands in docs/development.md) before opening a PR.
  3. Fill out the PR template's test checklist honestly — there's no application test suite to fall back on, so manual verification is the real bar here.
  4. Adding a fifth browser engine? See "Adding a future browser" in docs/browsers.md for the checklist.

License

MIT — this project is orchestration around other open-source components (Debian, Chromium, Firefox, x11vnc, noVNC) plus Microsoft's and Playwright's own distributions of Edge and WebKit; MIT keeps it maximally easy to adopt into an internal test pipeline without copyleft or patent-grant overhead. See docs/faq.md for the full reasoning.

Acknowledgments

Built on Debian, Chromium, Firefox, Microsoft Edge, WebKit via Playwright, Xvfb, Openbox, x11vnc, noVNC/websockify, and tini.

File reference

File What it does What to edit
browser.cmd Farm manager CLI — start/stop/scale containers, assign ports, validate BROWSER, load env Nothing, normally — see docs/development.md if you're adding a subcommand
env Runtime configuration for every container This — day to day
docker-compose.yml Defines the build (remote-browser-kit:1.0); not used at runtime Nothing
Dockerfile Image recipe — Debian + Xvfb + Openbox + Chromium (always) + Firefox/Edge/WebKit (opt-in build args) + x11vnc + noVNC, non-root browser user Only to add a system package or a new engine, then browser.cmd build
scripts/start.sh Browser-agnostic container entrypoint — validates BROWSER, starts every service in order, dispatches to the right launcher Nothing, normally
scripts/browsers/*.sh Per-engine launch flags and profile seeding Here, if you're changing one engine's behavior
scripts/healthcheck.sh Docker health check, runs every 20s Nothing
config/chromium-prefs.json Default profile template — Chromium and Edge Download behavior only; keep default_zoom_level: 0
config/firefox-prefs.js Default profile template — Firefox Same idea, Firefox user.js syntax
config/openbox-rc.xml Window manager config — maximize, no decorations Nothing
config/logrotate.conf Log rotation for /logs Retention period only

About

Docker-based remote browser platform with Chromium, Firefox, Edge, WebKit, VNC/noVNC, CDP, and automation support.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages