Docker Deployment
Docker Deployment
Section titled “Docker Deployment”Deploy Puppeteer MCP using Docker for consistent, isolated environments.
Quick Start
Section titled “Quick Start”Using Pre-built Image
Section titled “Using Pre-built Image”# Pull latest imagedocker pull williamzujkowski/puppeteer-mcp:latest
# Run containerdocker run -d \ --name puppeteer-mcp \ -p 3000:3000 \ -p 50051:50051 \ -e PUPPETEER_MCP_AUTH_TOKEN=your-secure-token \ williamzujkowski/puppeteer-mcp:latest
Using Docker Compose
Section titled “Using Docker Compose”Create docker-compose.yml
:
version: '3.8'
services: puppeteer-mcp: image: williamzujkowski/puppeteer-mcp:latest container_name: puppeteer-mcp ports: - '3000:3000' - '50051:50051' environment: - PUPPETEER_MCP_AUTH_TOKEN=${AUTH_TOKEN} - NODE_ENV=production - MAX_SESSIONS=10 restart: unless-stopped volumes: - ./config:/app/config deploy: resources: limits: memory: 2G cpus: '2'
Run with:
docker-compose up -d
Building Custom Image
Section titled “Building Custom Image”Basic Dockerfile
Section titled “Basic Dockerfile”FROM node:20-slim
# Install Chrome dependenciesRUN apt-get update && apt-get install -y \ chromium \ fonts-liberation \ libnss3 \ libatk-bridge2.0-0 \ libdrm2 \ libxkbcommon0 \ libxcomposite1 \ libxdamage1 \ libxfixes3 \ libxrandr2 \ libgbm1 \ libasound2 \ && rm -rf /var/lib/apt/lists/*
# Create app directoryWORKDIR /app
# Copy package filesCOPY package*.json ./
# Install dependenciesRUN npm ci --only=production
# Copy applicationCOPY . .
# Set Chrome pathENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=trueENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
# Create non-root userRUN useradd -m -u 1001 puppeteer && \ chown -R puppeteer:puppeteer /app
USER puppeteer
# Expose portsEXPOSE 3000 50051
# Health checkHEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ CMD curl -f http://localhost:8443/health || exit 1
# Start applicationCMD ["node", "dist/index.js"]
Production Dockerfile
Section titled “Production Dockerfile”# Build stageFROM node:20-alpine AS builder
WORKDIR /app
# Copy package filesCOPY package*.json ./COPY tsconfig.json ./
# Install all dependenciesRUN npm ci
# Copy sourceCOPY src ./src
# Build applicationRUN npm run build
# Runtime stageFROM node:20-slim
# Install Chrome and dependenciesRUN apt-get update && apt-get install -y \ chromium \ fonts-liberation \ libnss3 \ libatk-bridge2.0-0 \ libdrm2 \ libxkbcommon0 \ libxcomposite1 \ libxdamage1 \ libxfixes3 \ libxrandr2 \ libgbm1 \ libasound2 \ curl \ --no-install-recommends \ && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy package filesCOPY package*.json ./
# Install production dependencies onlyRUN npm ci --only=production && npm cache clean --force
# Copy built applicationCOPY --from=builder /app/dist ./dist
# Set environmentENV NODE_ENV=productionENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=trueENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
# Create non-root userRUN groupadd -r puppeteer && useradd -r -g puppeteer -G audio,video puppeteer \ && mkdir -p /home/puppeteer/Downloads \ && chown -R puppeteer:puppeteer /home/puppeteer \ && chown -R puppeteer:puppeteer /app
# Switch to non-root userUSER puppeteer
# Expose portsEXPOSE 3000 50051
# Health checkHEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ CMD curl -f http://localhost:8443/health || exit 1
# Start applicationCMD ["node", "dist/index.js"]
Docker Compose Examples
Section titled “Docker Compose Examples”Development Setup
Section titled “Development Setup”version: '3.8'
services: puppeteer-mcp: build: . container_name: puppeteer-mcp-dev ports: - '3000:3000' - '50051:50051' - '9229:9229' # Debug port environment: - NODE_ENV=development - PUPPETEER_MCP_AUTH_TOKEN=dev-token - PUPPETEER_HEADLESS=false - DEBUG=puppeteer:* volumes: - ./src:/app/src - ./config:/app/config command: npm run dev
Production Setup
Section titled “Production Setup”version: '3.8'
services: puppeteer-mcp: image: williamzujkowski/puppeteer-mcp:latest container_name: puppeteer-mcp restart: always ports: - '3000:3000' - '50051:50051' environment: - NODE_ENV=production - PUPPETEER_MCP_AUTH_TOKEN=${AUTH_TOKEN} - MAX_SESSIONS=20 - SESSION_TIMEOUT=1800000 - LOG_LEVEL=error volumes: - ./config:/app/config:ro - ./logs:/app/logs deploy: replicas: 3 resources: limits: memory: 2G cpus: '2' reservations: memory: 1G cpus: '1' healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8443/health'] interval: 30s timeout: 10s retries: 3 start_period: 40s
nginx: image: nginx:alpine container_name: puppeteer-nginx ports: - '80:80' - '443:443' volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - puppeteer-mcp
Container Configuration
Section titled “Container Configuration”Environment Variables
Section titled “Environment Variables”# RequiredPUPPETEER_MCP_AUTH_TOKEN=your-secure-token
# Browser configurationPUPPETEER_SKIP_CHROMIUM_DOWNLOAD=truePUPPETEER_EXECUTABLE_PATH=/usr/bin/chromiumPUPPETEER_ARGS="--no-sandbox --disable-setuid-sandbox"
# Server configurationPORT=3000GRPC_PORT=50051NODE_ENV=production
# Session managementMAX_SESSIONS=10SESSION_TIMEOUT=1800000
# SecurityCORS_ORIGIN=https://yourdomain.comRATE_LIMIT_MAX=100
Volume Mounts
Section titled “Volume Mounts”volumes: # Configuration files (read-only) - ./config:/app/config:ro
# Logs (read-write) - ./logs:/app/logs
# Temporary files - /tmp/puppeteer:/tmp/puppeteer
# Chrome user data (optional) - ./chrome-data:/home/puppeteer/.config/chromium
Resource Limits
Section titled “Resource Limits”deploy: resources: limits: memory: 2G # Maximum memory cpus: '2' # Maximum CPU cores reservations: memory: 1G # Minimum memory cpus: '0.5' # Minimum CPU cores
Security Considerations
Section titled “Security Considerations”1. Run as Non-Root
Section titled “1. Run as Non-Root”# Create non-root userRUN useradd -m -u 1001 puppeteerUSER puppeteer
2. Minimal Base Image
Section titled “2. Minimal Base Image”# Use slim or alpine variantsFROM node:20-slim# orFROM node:20-alpine
3. Security Scanning
Section titled “3. Security Scanning”# Scan image for vulnerabilitiesdocker scout cves williamzujkowski/puppeteer-mcp:latest
# Or use Trivytrivy image williamzujkowski/puppeteer-mcp:latest
4. Network Security
Section titled “4. Network Security”networks: backend: driver: bridge internal: true # No external access frontend: driver: bridge
Troubleshooting
Section titled “Troubleshooting”Chrome Won’t Start
Section titled “Chrome Won’t Start”# Error: Failed to launch chrome!
# Solution 1: Add Chrome flagsENV PUPPETEER_ARGS="--no-sandbox --disable-setuid-sandbox --disable-dev-shm-usage"
# Solution 2: Increase shared memorydocker run --shm-size=1gb ...
# Solution 3: Check dependenciesdocker exec -it puppeteer-mcp ldd /usr/bin/chromium | grep "not found"
Memory Issues
Section titled “Memory Issues”# Monitor memory usagedocker stats puppeteer-mcp
# Limit Chrome memoryENV PUPPETEER_ARGS="--max-old-space-size=1024"
# Use memory limitsdocker run -m 2g ...
Permission Errors
Section titled “Permission Errors”# Fix volume permissionsdocker exec -it puppeteer-mcp chown -R puppeteer:puppeteer /app/logs
# Or in DockerfileRUN mkdir -p /app/logs && chown -R puppeteer:puppeteer /app/logs
Kubernetes Deployment
Section titled “Kubernetes Deployment”Basic Deployment
Section titled “Basic Deployment”apiVersion: apps/v1kind: Deploymentmetadata: name: puppeteer-mcpspec: replicas: 3 selector: matchLabels: app: puppeteer-mcp template: metadata: labels: app: puppeteer-mcp spec: containers: - name: puppeteer-mcp image: williamzujkowski/puppeteer-mcp:latest ports: - containerPort: 3000 - containerPort: 50051 env: - name: PUPPETEER_MCP_AUTH_TOKEN valueFrom: secretKeyRef: name: puppeteer-secrets key: auth-token resources: limits: memory: '2Gi' cpu: '2' requests: memory: '1Gi' cpu: '500m' livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 30 periodSeconds: 10
Best Practices
Section titled “Best Practices”- Use Multi-Stage Builds - Reduce image size
- Pin Versions - Avoid unexpected updates
- Health Checks - Ensure container health
- Resource Limits - Prevent resource exhaustion
- Security Scanning - Regular vulnerability checks
- Logging - Centralized log collection
- Monitoring - Track performance metrics
Monitoring
Section titled “Monitoring”Prometheus Metrics
Section titled “Prometheus Metrics”# docker-compose.yml additionprometheus: image: prom/prometheus volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml ports: - '9090:9090'
Log Aggregation
Section titled “Log Aggregation”# docker-compose.yml additionfluentd: image: fluent/fluentd volumes: - ./fluent.conf:/fluentd/etc/fluent.conf - ./logs:/var/log/puppeteer
Next Steps
Section titled “Next Steps”- Set up Production Deployment
- Configure Monitoring
- Implement Scaling Strategies
- Review Security Best Practices