604d5e25c1
The mcr.microsoft.com/playwright images are language-agnostic Ubuntu images with only Chromium/Chrome/Firefox, no Python runtime. Reverting to python:3.11-slim for both admin and worker stages. Worker now installs Chromium via apt, patches ChromeDriver at build time, and uses the shared builder stage for dependency caching. This eliminates the broken venv, missing pip/uv, and registry mirror issues from previous iterations. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
95 lines
3.3 KiB
Docker
95 lines
3.3 KiB
Docker
# Usage:
|
|
# make build # Build all Docker images (admin + worker)
|
|
# docker compose up -d # Start all services
|
|
#
|
|
# Both admin and worker use python:3.11-slim — the builder stage
|
|
# is shared (caches deps), then:
|
|
# - admin: no Chrome needed (FastAPI only)
|
|
# - worker: installs Chromium + patches ChromeDriver for stealth
|
|
|
|
# ── Build args ─────────────────────────────────────────────────────────────────
|
|
ARG BASE_IMAGE=python:3.11-slim
|
|
|
|
# ── Stage 1: dependency resolver ─────────────────────────────────────────────
|
|
FROM python:3.11-slim AS builder
|
|
|
|
# Keep the build independent of GHCR; dependencies already use official PyPI.
|
|
RUN pip install --no-cache-dir uv==0.11.31
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy only dependency manifests first (cache layer)
|
|
COPY pyproject.toml uv.lock* ./
|
|
|
|
# Install deps into an isolated prefix so we can copy them cleanly
|
|
RUN uv sync --frozen --no-dev --no-install-project
|
|
|
|
# ── Stage 2a: admin runtime (python:3.11-slim, no Chrome) ────────────────────
|
|
FROM ${BASE_IMAGE} AS admin
|
|
|
|
WORKDIR /app
|
|
|
|
ENV PATH="/app/.venv/bin:$PATH" \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1
|
|
|
|
COPY . .
|
|
COPY --from=builder /app/.venv /app/.venv
|
|
|
|
RUN mkdir -p data logs recordings \
|
|
&& useradd -m -u 1001 seed \
|
|
&& chown -R seed:seed /app
|
|
|
|
USER seed
|
|
|
|
EXPOSE 8000
|
|
|
|
CMD ["python", "main.py", "admin"]
|
|
|
|
# ── Stage 2b: worker runtime (Python image with Chromium installed) ───────────
|
|
# Playwright Docker images don't ship Python — they're language-agnostic
|
|
# Ubuntu images with only Chromium/Chrome/Firefox. Reverting to python:3.11-slim
|
|
# for the worker so we get a working Python + pip out of the box.
|
|
FROM ${BASE_IMAGE} AS worker
|
|
|
|
ENV PATH="/app/.venv/bin:$PATH" \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
# Chromium binary (installed below)
|
|
CHROME_BINARY=/usr/bin/chromium \
|
|
CHROMEDRIVER_PATH=/app/drivers/chromedriver \
|
|
# Always run headless inside Docker
|
|
HEADLESS=true
|
|
|
|
WORKDIR /app
|
|
|
|
# Install Chromium + matching system ChromeDriver
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl chromium chromium-driver ffmpeg xvfb \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy manifests + lockfile first (stable cache layer)
|
|
COPY pyproject.toml uv.lock* ./
|
|
|
|
# Install deps into a venv
|
|
RUN pip install --no-cache-dir uv==0.11.31 \
|
|
&& uv sync --frozen --no-dev --no-install-project
|
|
|
|
# Copy app code (busts cache on code changes, not deps)
|
|
COPY . .
|
|
|
|
# Patch ChromeDriver at build time. This downloads the matching version,
|
|
# patches out undetected-chromedriver anti-detection flags, and places
|
|
# the binary at /app/drivers/chromedriver (configured via CHROMEDRIVER_PATH).
|
|
RUN PYTHONPATH=. python scripts/patch_driver.py \
|
|
&& mkdir -p data logs recordings
|
|
|
|
# Non-root user for safety
|
|
RUN useradd -m -u 1001 seed 2>/dev/null || true \
|
|
&& chown -R seed:seed /app 2>/dev/null || true
|
|
|
|
USER seed
|
|
|
|
# CMD is overridden in docker-compose.yml to use RQ worker
|
|
CMD ["rq", "worker", "--url", "redis://redis:6379/0", "batch"]
|