This document provides detailed instructions for running the Playwright MCP Server in Docker.
The Playwright MCP Server can be containerized using Docker, providing:
- Isolated execution environment
- Consistent runtime across different systems
- Easy deployment and distribution
- Simplified dependency management
- Docker installed on your system (Install Docker)
- Docker Compose (optional, usually included with Docker Desktop)
- The project built locally (
npm run build)
The Dockerfile is designed to work with pre-built artifacts and dependencies from your local build. Follow these steps:
-
Install production dependencies and build the project:
npm install --omit=dev npm run build
Or use the provided build script:
chmod +x docker-build.sh ./docker-build.sh
-
Manually build the Docker image:
docker build -t mcp-playwright:latest .Or with a specific tag:
docker build -t mcp-playwright:1.0.6 .
Important: The Dockerfile copies node_modules and dist from your local build directory. Make sure you have installed dependencies with --omit=dev flag before building the Docker image to keep the image size minimal.
Since MCP servers communicate via stdin/stdout, run the container in interactive mode:
docker run -i --rm mcp-playwright:latestFlags explained:
-i: Keep STDIN open for interactive communication--rm: Automatically remove the container when it exitsmcp-playwright:latest: The image name and tag
A docker-compose.yml file is provided for convenience:
# Start the server
docker compose run --rm playwright-mcp
# Build and run
docker compose build
docker compose run --rm playwright-mcpTo use the Dockerized MCP server with Claude Desktop, update your configuration file:
Location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Configuration:
{
"mcpServers": {
"playwright-docker": {
"command": "docker",
"args": ["run", "-i", "--rm", "mcp-playwright:latest"]
}
}
}For VS Code with MCP extension:
{
"name": "playwright-docker",
"command": "docker",
"args": ["run", "-i", "--rm", "mcp-playwright:latest"]
}You can pass environment variables to configure the server:
docker run -i --rm \
-e PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
mcp-playwright:latestIn docker-compose.yml:
services:
playwright-mcp:
environment:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
- NODE_ENV=productionIf you need to persist data or share files with the container:
docker run -i --rm \
-v $(pwd)/data:/app/data \
mcp-playwright:latestIn docker-compose.yml:
services:
playwright-mcp:
volumes:
- ./data:/app/data
- ./screenshots:/app/screenshotsMCP servers wait for input on stdin. Ensure you're running with -i flag:
docker run -i --rm mcp-playwright:latestThe Docker image skips browser downloads by default to reduce size. Playwright will download browsers on first use. To pre-install browsers, create a custom Dockerfile:
FROM mcp-playwright:latest
# Install Playwright browsers
RUN npx playwright install chromium --with-depsIf you encounter permission issues with mounted volumes:
docker run -i --rm \
-v $(pwd)/data:/app/data \
--user $(id -u):$(id -g) \
mcp-playwright:latestTo run the server on a custom network:
docker network create mcp-network
docker run -i --rm --network mcp-network mcp-playwright:latestLimit CPU and memory usage:
docker run -i --rm \
--cpus="2.0" \
--memory="2g" \
mcp-playwright:latestIn docker-compose.yml:
services:
playwright-mcp:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2GAdd a health check to your docker-compose.yml:
services:
playwright-mcp:
healthcheck:
test: ["CMD", "node", "-e", "process.exit(0)"]
interval: 30s
timeout: 10s
retries: 3The current Dockerfile is optimized for size:
- Uses Debian-based slim Node.js image (~200MB)
- Copies pre-built artifacts from host
- Production dependencies only
- Skips browser downloads by default
Current image size: ~200MB (without browsers)
-
Run as non-root user (optional but recommended):
FROM mcp-playwright:latest USER node
-
Read-only root filesystem (if applicable):
docker run -i --rm --read-only mcp-playwright:latest
-
Scan for vulnerabilities:
docker scan mcp-playwright:latest
If you prefer to build inside Docker (not using pre-built dist):
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
RUN npm ci
COPY src ./src
COPY tsconfig.json ./
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
CMD ["node", "dist/index.js"]For issues related to Docker:
- Check the main README.md for general information
- Report Docker-specific issues on GitHub Issues
- Tag your issue with
dockerlabel