
Deploy Selenium Grid 4.46 | Hub + Chromium and Firefox Nodes, Password-Protected
Hub plus private Chromium and Firefox nodes, password-protected
Just deployed
node-chromium
Just deployed
node-firefox
Just deployed
Deploy and Host Selenium Grid on Railway
Selenium Grid runs your browser tests in parallel across several browsers at once. This template deploys Selenium Grid 4.46 as three services — a public hub plus a Chromium node and a Firefox node on Railway's private network — with the router password-protected.
About Hosting Selenium Grid
The hub is the only service with a public URL. Nodes register with it over *.railway.internal, so the browsers themselves are never reachable from the internet, and scaling a browser is changing one service's replica count rather than redeploying the stack.
A Grid router executes whatever the caller asks a browser to do, from inside your project's network. Published on a public URL with no credentials — how the stock images ship, and how the existing Selenium listings deploy — that is an open remote-execution endpoint for anyone who finds the hostname. This template enables Grid's built-in router basic auth, generates the password per deploy, hands it to the nodes through their registration URL, and the hub image refuses to boot with an empty password.
The rest is Railway-specific plumbing the stock images cannot know about. The hub honours Railway's injected $PORT, because Railway's healthcheck dials the injected port and not the domain's target port, so a hub pinned to 4444 serves 200 to the world while its deploy is failed. Nodes keep their own registration port (5555) instead, because the hub dials them back over the private network where no edge proxy is involved. Session count is pinned to 2 per node with override-max-sessions, because nproc inside a container reports the host's cores and Selenium's automatic min(cpus, 8) sizes itself for the metal. The Chromium node carries --disable-dev-shm-usage on every session, since a container gets 64 MB of /dev/shm and upstream's fix (docker run --shm-size=2g) is not a knob a Railway deploy has; the Firefox node deliberately does not, because geckodriver refuses a session that carries it.
Images are pinned to 4.46.0-20260707 — Chromium 150, Firefox 152. Upstream's :latest moves weekly and carries a new major browser with it, so an unpinned grid does not reproduce last week's test run.
Why Deploy Selenium Grid on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Selenium Grid on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
- Cross-browser in one endpoint — ask for
browserName: "chrome"or"firefox"at the same URL and the hub routes it. - Not an open grid — router basic auth by default, password generated per deploy, nodes private.
- Scale a browser, not the stack — raise a node service's replicas or
SE_NODE_MAX_SESSIONSwhen the queue grows. - Pinned and reproducible — Selenium 4.46.0 with fixed browser versions.
Common Use Cases
- Parallel CI suites — run a test matrix across Chromium and Firefox against one hosted grid instead of installing browsers on every runner.
- Cross-browser regression checks — catch the Gecko-only failure a Chromium-only suite never sees.
- Scheduled scraping and monitoring — render JavaScript-heavy pages on a schedule from a fixed address.
- AI agents that browse — give agents real browsers over WebDriver, isolated in their own Railway project.
Dependencies for Selenium Grid Hosting
- No database and no volume — sessions are ephemeral by design.
- Three services: hub (light), Chromium node and Firefox node (2 GB RAM each is comfortable at the default two sessions).
Deployment Dependencies
- SeleniumHQ/docker-selenium — the upstream hub and node images (Apache-2.0)
- bon5co/selenium-railway — the Railway-tuned wrappers this template deploys
- Selenium Grid documentation — architecture and client setup
Implementation Details
Point any WebDriver client at the hub and name the browser you want:
from selenium import webdriver
for options in (webdriver.ChromeOptions(), webdriver.FirefoxOptions()):
options.add_argument("--headless")
driver = webdriver.Remote(
command_executor="https://selenium:PASSWORD@YOUR-HUB-DOMAIN.up.railway.app/wd/hub",
options=options,
)
driver.get("https://example.com")
print(options.capabilities["browserName"], driver.title)
driver.quit()
GET /status on the hub (same credentials) lists every registered node and its free slots — the fastest check that a node came back after a redeploy. Adding a browser is adding a service from ghcr.io/bon5co/selenium-node--railway with SE_EVENT_BUS_HOST, SE_NODE_HOST and SE_NODE_GRID_URL copied from an existing node.
Variables you may want to change: SE_NODE_MAX_SESSIONS (default 2, per node), SE_NODE_SESSION_TIMEOUT (default 300s), SE_ROUTER_USERNAME (default selenium).
Template Content