Docker for Selenium Grid: Complete 2026 Setup Guide
Complete Docker for Selenium Grid setup guide for 2026. Run Selenium tests in containers, scale to 100+ parallel sessions with Docker Compose & Kubernetes, and integrate with CI/CD.

Last updated: June 29, 2026 · Reading time: 9 minutes · By SoftwareTestPilot Editorial Team
What you'll build: A production-ready Selenium 4 Grid in Docker — hub + Chrome + Firefox nodes via Docker Compose, dynamic scaling, video recording, GitHub Actions integration, and Kubernetes manifests for hundreds of parallel sessions.
Why Docker for Selenium?
- Consistent environment — same OS, browsers, drivers across dev/CI/prod
- Easy parallel execution — 10+ browser instances on one machine
- Scalable — Kubernetes for hundreds of parallel sessions
- Reproducible — versioned images for browser/driver combinations
For broader Selenium context, pair this with our Selenium WebDriver Guide, the GitHub Actions Selenium CI setup, and the CI/CD Pipeline Testing Tutorial.
Step 1 — Prerequisites
- Docker Desktop or Docker Engine installed
- Docker Compose v2+
- 4 GB RAM minimum (8 GB+ for production)
- Selenium 4 Java/Python project
Step 2 — Basic Docker Compose Setup
Create docker-compose.yml:
version: '3.8'
services:
selenium-hub:
image: selenium/hub:4.25
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PORT=4443
chrome:
image: selenium/node-chrome:4.25
depends_on:
- selenium-hub
shm_size: 2gb
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_HOST=chrome
- SE_NODE_PORT=5555
firefox:
image: selenium/node-firefox:4.25
depends_on:
- selenium-hub
shm_size: 2gb
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_HOST=firefox
- SE_NODE_PORT=5555Step 3 — Start the Grid
docker-compose up -dVerify it's running:
curl http://localhost:4444/statusShould return {"value":{"ready":true,"message":"Selenium Grid ready...","nodes":[...]}}.
Step 4 — Run Tests Against the Grid
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver = new RemoteWebDriver(
new URL("http://localhost:4444/wd/hub"),
options
);from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
driver = webdriver.Remote(
command_executor="http://localhost:4444/wd/hub",
options=options
)For Java setup, see our Java for Selenium tutorial; for Python, the Selenium Python Q&A.
Step 5 — Scale Horizontally
Add more nodes:
chrome-2:
image: selenium/node-chrome:4.25
depends_on:
- selenium-hub
shm_size: 2gb
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
chrome-3:
image: selenium/node-chrome:4.25
depends_on:
- selenium-hub
shm_size: 2gb
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443Or scale dynamically:
docker-compose up -d --scale chrome=5Now you have 5 Chrome nodes.
Step 6 — View the Grid Console
Open http://localhost:4444 in your browser. You'll see:
- Active sessions
- Node capacity
- Queued requests
Step 7 — Add Video Recording
chrome:
image: selenium/node-chrome:4.25
shm_size: 2gb
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_ENABLE_TRACING=true
volumes:
- ./videos:/opt/selenium/videosVideos saved to ./videos for debugging.
Step 8 — CI/CD Integration
GitHub Actions
name: Selenium Grid Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- name: Start Selenium Grid
run: docker-compose up -d
- name: Wait for Grid
run: |
until curl -sf http://localhost:4444/status; do
echo "Waiting for grid..."
sleep 5
done
- name: Run Tests
run: mvn test
- name: Stop Grid
if: always()
run: docker-compose downStep 9 — Kubernetes Deployment
For production-scale Selenium Grid:
# selenium-hub.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: selenium-hub
spec:
replicas: 1
selector:
matchLabels:
app: selenium-hub
template:
metadata:
labels:
app: selenium-hub
spec:
containers:
- name: hub
image: selenium/hub:4.25
ports:
- containerPort: 4442
- containerPort: 4443
- containerPort: 4444
---
apiVersion: v1
kind: Service
metadata:
name: selenium-hub
spec:
selector:
app: selenium-hub
ports:
- port: 4444
targetPort: 4444# selenium-node.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: selenium-node-chrome
spec:
replicas: 5
selector:
matchLabels:
app: selenium-node
template:
metadata:
labels:
app: selenium-node
spec:
containers:
- name: chrome
image: selenium/node-chrome:4.25
env:
- name: SE_EVENT_BUS_HOST
value: selenium-hub
- name: SE_EVENT_BUS_SUBSCRIBE_PORT
value: "4443"Step 10 — Best Practices
Do
- Use named volumes for video/screenshot persistence
- Set memory limits (
mem_limit: 2g) - Use
--scalefor dynamic node count - Run in headless mode in CI
- Set retry policy for flaky tests
Don't
- Don't run too many nodes on one machine (memory limits)
- Don't run in non-headless mode in CI
- Don't expose the grid publicly without authentication
- Don't ignore resource limits
Common Issues
"No route to host"
Fix: Ensure all nodes can reach the hub. Check SE_EVENT_BUS_HOST.
"Session not created"
Fix: Browser/driver version mismatch. Use the same Selenium version for hub and nodes.
Out of memory
Fix: Reduce number of parallel sessions per node, or increase host memory.
Advanced Docker Patterns
Pattern 1 — Multi-arch builds
Build images for both ARM64 (Apple Silicon) and AMD64:
FROM --platform=$BUILDPLATFORM selenium/node-chrome:4.25
# ...Use docker buildx for multi-arch builds.
Pattern 2 — Health checks
chrome:
image: selenium/node-chrome:4.25
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5555/status"]
interval: 30s
timeout: 10s
retries: 3Pattern 3 — Resource limits
chrome:
image: selenium/node-chrome:4.25
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512MPattern 4 — Secrets management
secrets:
- browserstack_key
services:
chrome:
image: selenium/node-chrome:4.25
secrets:
- browserstack_keyPattern 5 — Health monitoring
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"