Repository navigation
feat(docker): add a Chrome driver and images to replace browserless - #645
Merged
Merged
Conversation
A small Go server that looks like browserless v2 from the outside but runs no Puppeteer: each WebSocket connection gets its own Chrome, traffic is proxied unchanged, and Chrome's process group is killed when the connection ends. /json/version starts the session's Chrome and returns its real metadata with a reachable ws URL; unclaimed browsers are stopped after 30s. DESIGN.md lists the browserless pitfalls it avoids.
… and document them in --help
…t --remote-allow-origins
…9 with Retry-After
…aken by another connection With ws_url:, Ferrum calls /json/version and then connects to /, which claims any pending Chrome with the same query. With parallel clients that can be the Chrome another client's /json/version started, and that client then got 404 on /devtools/browser/<id>. Chromes started with the same query are interchangeable, so the id route now falls back the same way.
…hanging on a stuck browser
…aunch.headless is false
… acting as a fake Chrome
… the docker images
… publishing them FERRUM_URL points the suite at a driver. CI passes Ferrum's default window size and --disable-web-security in the launch query, so the specs see the same browser as locally. The custom browser path spec needs a local browser and skips remotely.
…sign status up to date
…s only one browser
…M_URL points at a remote one
…owsers that changed A scheduled run compares the newest Chrome (Google's apt repository) and Chromium (Debian's apt-cache policy) with the tags on GHCR. The version is a build arg, so a new release busts the layer cache, and the image is labeled with the driver's commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Better than browserless, not equal to it. A self-hosted Chrome service for Ferrum and Cuprite users: a small Go driver (
docker/) and two images,ghcr.io/rubycdp/chromeandghcr.io/rubycdp/chromium, each for amd64 and arm64. Moving from browserless usually means swapping the image and connecting to/.Open http://localhost:3000 in a browser to see running sessions and inspect their pages live in DevTools.
Why
Most remote-Chrome issues reported here come from browserless's own logic, not from CDP. Its Puppeteer resets the viewport (#592, #492), it writes a raw HTTP 408 onto a live socket (#538), it reports
0.0.0.0as the WebSocket host (#501), and it leaves Chrome processes and zombies behind (#505, #364).docker/DESIGN.mdlists all of them and compares the driver with browserless v2.How
httputil.ReverseProxy. Nothing else talks to the client's targets./json/versionis answered on the fly. It starts the session's Chrome, returns its real metadata, and rewrites the ws URL to a reachable host while keeping the query. A Chrome nobody connects to is stopped after 30s. Connections to/claim a Chrome already started with the same query, falling back to another pending one if the id was taken.launch(JSON or base64) takesargs,defaultViewport,ignoreDefaultArgsandheadless;headless: falseruns Chrome on its own Xvfb display.timeoutsets a session timeout.CONCURRENT(default: CPUs) andQUEUED(default 10), answering429withRetry-Afterbefore the upgrade.TIMEOUTis off by default.EXTERNAL/PROXY_URLset the advertised address behind a proxy.dockerize: truelocally, window size included, except--remote-allow-origins./json,/json/list,/json/new,/json/protocol,/devtools/page/<id>and the DevTools frontend, with URLs pointing at the driver./. Running sessions and their pages, each linking to DevTools; every "session opened" log line links to it.driver --helpdocuments env, endpoints, launch options and the default flags.debian:trixie-slimwith dumb-init as PID 1, and aHEALTHCHECKon/health..deb) or Debian Chromium. No Node.org.opencontainers.image.revisionlabel..github/workflows/docker.yml).go test -racegate the builds.local_browser, which start their own Chrome, are skipped whenFERRUM_URLis set.mainit publisheslatest, the major and the full browser version as multi-arch tags. A failed build or suite publishes nothing.Testing
-race, using the test binary as a fake Chrome.url:andws_url:flows, launch options, headful under Xvfb, parallel sessions withCONCURRENT/QUEUED, timeouts, the dashboard and DevTools on a live page, and no Chrome or zombie processes left behind.Not in this PR
window_sizeremotely,Browser#debugin remote mode, and never looking for a local binary whenurlorws_urlis set.ReverseProxy.