Sometimes GitHub Actions is not enough. You need to run tests locally in the exact same environment as CI. Or your CI is Jenkins and you want reproducible builds. Or you need to run the app and tests together. Docker solves all of these.
Microsoft maintains official Docker images for Playwright. These come with all browsers and system dependencies pre-installed. No need for npx playwright install --with-deps inside the container.
# Pull the official Playwright image
docker pull mcr.microsoft.com/playwright:v1.48.0-jammy
# Run tests inside the container
docker run --rm -v $(pwd):/app -w /app \
mcr.microsoft.com/playwright:v1.48.0-jammy \
bash -c "npm ci && npx playwright test"
# Interactive mode -- useful for debugging
docker run -it --rm -v $(pwd):/app -w /app \
mcr.microsoft.com/playwright:v1.48.0-jammy \
bashFROM mcr.microsoft.com/playwright:v1.48.0-jammy
WORKDIR /app
# Copy package files first for better layer caching
COPY package.json package-lock.json ./
RUN npm ci
# Copy test files and config
COPY playwright.config.ts ./
COPY tests/ ./tests/
# Run tests
CMD ["npx", "playwright", "test"]This is the real power of Docker. Run your web app in one container and Playwright tests in another. Tests wait for the app to be ready, then run against it.
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=test
- DATABASE_URL=postgresql://postgres:postgres@db:5432/testdb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=testdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
playwright:
image: mcr.microsoft.com/playwright:v1.48.0-jammy
working_dir: /app
volumes:
- .:/app
- /app/node_modules
environment:
- CI=true
- BASE_URL=http://app:3000
command: >
bash -c "
npm ci &&
npx wait-on http://app:3000 --timeout 60000 &&
npx playwright test
"
depends_on:
- app# Run the full stack + tests
docker compose -f docker-compose.test.yml up --abort-on-container-exit
# Rebuild and run (after code changes)
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit
# Clean up
docker compose -f docker-compose.test.yml down -vThe Playwright Docker image is large -- about 2 GB. The first pull takes time. Use specific version tags (v1.48.0-jammy) not latest. The latest tag might update and break your tests without warning.
Use --abort-on-container-exit with docker compose. Without it, the app and database containers keep running after tests finish. With it, everything shuts down when the test container exits.
Q: How do you run Playwright tests in Docker?
A: Use the official Microsoft Playwright Docker image: mcr.microsoft.com/playwright:v1.48.0-jammy. It comes with all browsers and system dependencies pre-installed. Mount your project as a volume, install npm dependencies, and run tests. For full-stack testing, use docker-compose with separate containers for the app, database, and Playwright. The test container waits for the app using wait-on, then runs tests against it. Always pin the image version tag -- never use latest.
Key Point: Docker gives you identical test environments everywhere. Use the official Playwright image with a pinned version tag. Docker Compose lets you run app + database + tests together.
Key Point: Use the official Playwright Docker image for consistent environments. Docker Compose runs your app, database, and tests together.