Skip to content

Commit 8d902c9

Browse files
authored
fix(templates): Pin playwright to base image version in uv Dockerfile template (#1904)
## Summary The `uv` package-manager branch of the actor Dockerfile template (`src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile`) doesn't pin Python `playwright` to the version pre-installed in the Apify base image. When the lockfile resolves to a different `playwright` version than the base image (currently 1.59.0 vs the base image's 1.60.0 + chromium-1223), the actor tries to launch a Chromium build that `/pw-browsers/` doesn't ship and fails with `Executable doesn't exist at /pw-browsers/chromium_headless_shell-1217/...`. The pip and poetry branches solve this by sed-rewriting `playwright==X.Y.Z` to whatever `playwright --version` reports in the image. The uv branch's `--no-install-package playwright` was supposed to be the equivalent, but the test's `pip install crawlee --force-reinstall` (and any user step that touches playwright before the `uv sync` runs) defeats it. This fix mirrors the pip/poetry intent for uv: - **Snapshot** the base image's `playwright --version` in the early `pip install uv` layer, before `COPY pyproject.toml uv.lock ./` or any test-injected step can mutate it. - After `uv sync ... --no-install-package playwright`, check if the env's playwright still matches; if it has drifted, force-reinstall with `uv pip install --reinstall --no-deps "playwright==<base-version>"`. - Guard the reinstall behind a version check so the common case (no drift) skips the wheel download. Resolves the 9 failing `uv`-variant scheduled e2e jobs in [run 26082797876](https://github.com/apify/crawlee-python/actions/runs/26082797876) (`playwright`, `adaptive_beautifulsoup`, `adaptive_parsel` × {httpx, curl_impersonate, impit}). Verified against the live `apify/actor-python-playwright:3.13` image: | Scenario | Before | After | | --- | --- | --- | | Real user, no drift | works, but `pip freeze \| grep playwright` check is brittle | guard short-circuits, no extra work | | Test injection downgrades playwright to 1.59.0 | mismatched chromium → crash | reinstall pins to 1.60.0, browsers match |
1 parent d424901 commit 8d902c9

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

  • src/crawlee/project_template/{{cookiecutter.project_name}}

src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ RUN echo "Python version:" \
4141
&& echo "All installed Python packages:" \
4242
&& pip freeze
4343
# % elif cookiecutter.package_manager == 'uv'
44-
RUN pip install -U pip setuptools \
45-
&& pip install 'uv<1'
44+
COPY --from=ghcr.io/astral-sh/uv:0.11 /uv /uvx /bin/
45+
46+
# Snapshot the base image's playwright version before uv sync so we can pin to it later
47+
# and stay aligned with the browser binaries baked into /pw-browsers.
48+
RUN hash playwright 2>/dev/null && playwright --version | cut -d ' ' -f 2 > /tmp/.base-playwright-version || true
4649

4750
ENV UV_PROJECT_ENVIRONMENT="/usr/local"
4851

@@ -51,15 +54,13 @@ COPY pyproject.toml uv.lock ./
5154
RUN echo "Python version:" \
5255
&& python --version \
5356
&& echo "Installing dependencies:" \
54-
# Check if playwright is already installed
55-
&& PLAYWRIGHT_INSTALLED=$(pip freeze | grep -q playwright && echo "true" || echo "false") \
56-
&& if [ "$PLAYWRIGHT_INSTALLED" = "true" ]; then \
57-
echo "Playwright already installed, excluding from uv sync" \
58-
&& uv sync --frozen --no-install-project --no-editable -q --no-dev --inexact --no-install-package playwright; \
59-
else \
60-
echo "Playwright not found, installing all dependencies" \
61-
&& uv sync --frozen --no-install-project --no-editable -q --no-dev --inexact; \
57+
&& uv sync --frozen --no-install-project --no-editable --quiet --no-dev --inexact \
58+
&& PLAYWRIGHT_BASE_VERSION=$(cat /tmp/.base-playwright-version 2>/dev/null || echo "") \
59+
&& if [ -n "$PLAYWRIGHT_BASE_VERSION" ]; then \
60+
echo "Pinning playwright to $PLAYWRIGHT_BASE_VERSION to match the browser binaries shipped in the base image" \
61+
&& uv pip install --reinstall --no-deps "playwright==$PLAYWRIGHT_BASE_VERSION"; \
6262
fi \
63+
&& rm -f /tmp/.base-playwright-version \
6364
&& echo "All installed Python packages:" \
6465
&& pip freeze
6566
# % elif cookiecutter.package_manager == 'pip'

0 commit comments

Comments
 (0)