Docker
The official Playwright Docker image already has all three browsers and every system dependency installed. Using it in CI means I skip the 'npx playwright install --with-deps' step entirely — I just npm ci and run tests. The two flags I always add: --ipc=host (Chromium crashes without it) and --init (zombie process prevention).
Why use the Docker image instead of installing browsers on the runner
The main reason I use the Docker image on CI: consistency. The same Ubuntu base, the same browser versions, the same system libraries — regardless of which runner picks up the job. I've had visual regression tests fail because the runner had a slightly different libpango version that changed text rendering. Docker eliminates that class of problem.
The image is at mcr.microsoft.com/playwright:v1.x-noble (Ubuntu 24.04) or v1.x-jammy (Ubuntu 22.04). The Playwright npm package itself is NOT in the image — you still run npm ci to install it. The image only provides browsers and system dependencies.
The flags that actually matter when running
--ipc=host — this one bites people. Chromium uses shared memory between the browser process and renderer processes. Docker containers have a tiny /dev/shm by default (64MB). Chromium exceeds this and crashes with cryptic errors. --ipc=host makes the container share the host's IPC namespace, giving Chromium enough memory.
--init — without it, PID 1 inside the container is your shell or Node process. PID 1 has special signal-handling behavior that can cause child processes (browser sub-processes) to become zombies that never get cleaned up. --init puts a proper init process at PID 1.
Using the image in CI
In GitHub Actions, using the image as a container means I skip the browser install step. The CI job just installs npm packages and runs tests — browsers are already there.
Note the --user 1001 option — GitHub Actions runs as a non-root user by default, and the container needs to match. Without this you get permission errors on the workspace files.
Running Playwright server in Docker, tests on the host
Sometimes I want browsers inside Docker but the tests running locally — useful when I'm on a Mac but need Linux browser behavior. I start the Playwright server in Docker and connect to it via websocket.