4.3 KiB
name, description, source, extracted_at
| name | description | source | extracted_at |
|---|---|---|---|
| playwright-base-docker | Use mcr.microsoft.com/playwright as a pre-baked Chrome base image for Dockerized crawler/automation projects | auto-skill | 2026-08-04T18:21:03.395Z |
Problem
Dockerizing headless Chrome automation requires Chromium, matching ChromeDriver, Xvfb, ffmpeg, and browser patching — which bloats the image and adds build steps.
Approach
Use mcr.microsoft.com/playwright:<version>-noble (or similar variant) as the base image for worker/crawler services. Playwright ships with Chromium, ChromeDriver, and common browser automation dependencies pre-installed and pre-patched.
Key steps
-
Define multi-stage Dockerfile with separate targets
admintarget: lightweightpython:3.11-slim(no Chrome needed for FastAPI)workertarget:mcr.microsoft.com/playwright:v1.62.0-noble(Chrome + deps included)
-
Do NOT copy
.venvfrom a different Python version builder stage- The Playwright Noble image ships Python 3.12 while
python:3.11-slimships 3.11. - Copying a 3.11-built venv into the image produces broken shebangs —
exec /app/.venv/bin/rq: no such file or directory(the binaries exist but their#!line points to a non-existent Python 3.11). - Fix: install
uvinside the worker stage and runuv syncnatively so the venv targets the image's Python.
- The Playwright Noble image ships Python 3.12 while
-
Installing
uvin the Playwright image- Playwright ships Python but not
piporuvin PATH. - Working approach:
RUN python -m ensurepip --upgrade \ && python -m pip install --no-cache-dir --break-system-packages uv==0.11.31 \ && uv sync --frozen --no-dev --no-install-project ensurepipbootstraps pip in the same shell, thenpython -m pipinstalls theuvCLI into/usr/local/bin/uv(already in PATH).- Do NOT try to set
ENV PATHin a separate layer before callinguv— the install script doesn't modify PATH, and the binary won't be found. - Avoid
curl -LsSf https://astral.sh/uv/install.sh | shin a RUN followed byuvin the next — the install script is a one-shot that doesn't persist PATH.
- Playwright ships Python but not
-
Set environment variables for Chrome location and headless mode:
ENV CHROME_BINARY=/usr/bin/chromium \ CHROMEDRIVER_PATH=/usr/bin/chromedriver \ HEADLESS=true -
Skip
patch_driver.py— Playwright's Chromium is already pre-patched with undetected-chromedriver-friendly modifications. -
Update docker-compose.yml with explicit build targets:
admin: build: context: . dockerfile: Dockerfile target: admin worker: build: context: . dockerfile: Dockerfile target: worker
Common pitfalls
//inFROMlines doesn't work:FROM oci.reg.darano.ir//mcr.microsoft.com/playwright:latest AS workerwill fail withinvalid reference format. The Docker parser confuses//with theASsyntax. If your registry requires//for internal routing, configure it at the Docker daemon level in/etc/docker/daemon.jsonunderregistry-mirrors, not in the Dockerfile.- Don't copy venv from python:3.11-slim to Playwright: Python version mismatch → broken shebangs. Always build the venv natively in the target stage.
- Don't rely on
pipbeing available: Playwright ships Python without pip. Usepython -m ensurepipfirst.
What you still need
- ffmpeg and Xvfb: The Playwright image includes these for session recording. If you need them for headless mode only (no recording), they are optional.
- security_opt: Workers still need
cap_add: [SYS_ADMIN]andsecurity_opt: [seccomp:unconfined]for undetected-chromedriver to fully spoof browser fingerprints. - shm_size: Keep
shm_size: "2gb"on worker containers to prevent Chrome OOM crashes.
Files changed
Dockerfile— split intoadminandworkertargetsdocker-compose.yml— explicittargetper service, separate image names
Why this matters
- Faster builds — no Chromium download, no ChromeDriver version matching, no patching script
- Smaller admin image — admin panel doesn't need any browser dependencies
- Reliable driver matching — Playwright maintains its own bundled Chromium/ChromeDriver pair, eliminating version mismatches