Deploying Grid with Containers, Kubernetes, and Cloud Infrastructure: Core Concepts and Mental Model
Chapter 19 explained how Grid routes a session. Chapter 20 moves one layer outward: the Grid itself now runs inside containers or an orchestrator. That changes networking, storage, resource accounting, security boundaries, upgrade mechanics, and how a browser reaches the application under test.
Learning objectives
- Trace test traffic through host/CI, containerized Grid services, browser container or pod, and the AUT network.
- Separate image identity, container runtime state, browser session state, persistent artifacts, and orchestration state.
- Explain why container localhost is not the host or another container.
- Inspect image/server/browser/capability state before mutating infrastructure.
- Describe Kubernetes/cloud boundaries without requiring a cluster or paid browser service.
1. Why “it works locally” changes when the browser moves into a container
A local browser shares the test runner’s machine namespace. A containerized browser does not. The browser now resolves DNS, opens TCP connections, writes downloads, consumes shared memory, and emits logs from a separate runtime boundary. A test can therefore fail before Selenium ever reaches a locator.
127.0.0.1 and localhost are relative to
the process that uses them. From inside a browser container,
http://localhost:8080 means port 8080 inside that
browser container—not the developer workstation and not an AUT
container.
2. The deployment path and trust boundaries
The following diagram visualizes the relationships described in The deployment path and trust boundaries. Read the nodes in sequence and use the arrows to connect the conceptual state changes to the explanation around the diagram.
flowchart TD T[Test runner / CI] -->|WebDriver HTTP| G[Grid endpoint :4444] G --> N[Browser Node container / pod] N -->|AUT HTTP/TLS| A[Application under test] N --> E[Ephemeral browser/profile state] N --> F[Optional artifacts / video / logs] O[Docker / Kubernetes] -->|start, stop, restart, limits| G O -->|start, stop, restart, limits| N S[Secrets / registry / network policy] --> O
The test client owns test intent and credentials. Grid owns session routing. The browser container owns browser processes and temporary profile state. Docker or Kubernetes owns process isolation, networks, mounts, restarts, and resource limits. Artifact stores outlive a session only when you deliberately mount or upload them. A hosted browser cloud replaces parts of this infrastructure, but it does not remove the same trust questions.
3. State stores you must not blur together
The following table organizes the key choices and evidence for State stores you must not blur together. Use it together with the surrounding prose so the rows serve as a comparison aid rather than standalone rules.
| State | Owner / lifetime | Examples | Safe default |
|---|---|---|---|
| Image | Registry; immutable by digest/tag intent | Grid/browser binaries, OS packages | Use full Selenium release tags; verify digest for stricter supply-chain control |
| Container/pod runtime | Docker/Kubernetes; ephemeral | PID namespace, filesystem layer, network namespace | Disposable; recreate rather than hand-edit |
| WebDriver session | Grid/Node until quit/timeout | session ID, capabilities, browser profile | One test/session policy where practical |
| Artifact state | Mounted path or external store | screenshots, video, logs | Per-session directory + bounded retention |
| Secret/config state | CI/Kubernetes secret/config store | cloud credentials, registry auth | Never bake into image or print to logs |
4. Read-only preflight before starting or changing Grid
The following example makes the Read-only preflight before starting or changing Grid behavior concrete. Read it with the stated assumptions, then compare its observable output or state changes with the explanation that follows.
docker version
docker compose version
docker image inspect selenium/standalone-chrome:4.47.0-20260808 --format '{{.RepoTags}} {{.Id}}' 2>/dev/null || true
# After Grid is running:
curl -fsS http://127.0.0.1:4444/status
The following example makes the Read-only preflight before starting or changing Grid behavior concrete. Read it with the stated assumptions, then compare its observable output or state changes with the explanation that follows.
import json, urllib.request
with urllib.request.urlopen("http://127.0.0.1:4444/status", timeout=3) as response:
status = json.load(response)
print(json.dumps(status, indent=2)[:2000])
Inspect first: Docker/Compose versions, the exact image tag, Grid readiness, returned capabilities, browser version, session ID, and current URLs. Do not diagnose a browser issue while silently running a different image than the one documented in CI.
5. Version pinning: stable release tags, not floating intent
The official Docker Selenium project currently publishes
4.47.0-20260808 images. Its own README recommends full
tags for reproducibility and labels nightly as
test-only. A short latest tag can change Grid, browser,
driver, OS, and Java together between runs.
| Choice | Reproducibility | Use |
|---|---|---|
selenium/standalone-chrome:4.47.0-20260808
|
High for a release image | Course and controlled CI baseline |
:4.47.0 |
Less explicit than dated release tag | Convenience, but weaker forensic identity |
:latest |
Floating | Avoid for release gates |
:nightly |
Snapshot / pre-release | Compatibility experiments only |
6. Browser containers are resource workloads, not tiny utilities
The official project recommends --shm-size=2g for
browser-containing images. Shared-memory pressure can look like
browser crashes or renderer instability. CPU, memory, file
descriptors, video encoders, downloads, and parallel sessions all
compete for host resources.
Do not fix crashes by adding --privileged, disabling
the sandbox globally, or raising concurrency blindly. Measure
browser/session resource use and set realistic limits. Video is
optional evidence and consumes additional CPU/storage.
7. Kubernetes and browser clouds change the operator, not the test contract
On Kubernetes, pods replace long-lived containers and
Services/Ingress replace direct port publishing. The official
Selenium project currently publishes Helm chart
0.58.0 using image tag 4.47.0-20260808.
Managed browser clouds move browser/runtime operations to a
provider. In both cases the test still needs a reachable Grid
endpoint, reachable AUT, explicit capabilities, evidence
correlation, secret handling, and cleanup.
8. DevOps operating model
Treat Grid images like deployable software: pin versions, review upgrades, record image/server/browser identity in CI artifacts, restrict ingress, define resource budgets, measure queue/session health, keep artifacts bounded, and rehearse rollback. A green Selenium test cannot prove the Grid deployment itself is securely operated.
Knowledge check
Why can http://localhost:8000 work from the test
runner but fail inside a Grid browser container?
Because localhost is resolved inside each network namespace. The browser container needs a route/DNS name to the AUT host or service.
What survives when a browser container is recreated by default?
Only state stored outside its writable container layer—such as a mounted artifact directory or external service. The WebDriver session/profile is ephemeral.
Why pin 4.47.0-20260808 instead of
latest?
The full release tag makes Grid/browser/driver image identity reviewable and repeatable; a floating tag can change without a test-code change.
Does Kubernetes readiness prove a browser session can reach the AUT?
No. Pod readiness says the configured readiness probe passes. Browser readiness and AUT network reachability are separate observable conditions.
Is exposing port 4444 publicly a harmless convenience?
No. Grid is powerful infrastructure and must be restricted to trusted networks/authentication boundaries; public exposure can enable access to internal resources and arbitrary browser activity.
Official references and current-version notes
- SeleniumHQ/docker-selenium — official images, Compose, Dynamic Grid, troubleshooting
- Docker Selenium 4.47.0-20260808 release
- Official Selenium Grid Helm chart
- Selenium Grid documentation
- Grid CLI/configuration options
These lessons pin Selenium Python and Grid concepts to
4.47.0, Docker Selenium image tag
4.47.0-20260808, and Helm chart 0.58.0.
The nightly images track Selenium 4.48.0-SNAPSHOT and
are intentionally excluded from the mandatory path.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.