From 709d61a1918c494ec873cabd715c693cfc897195 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Tue, 19 May 2026 10:39:01 +0200 Subject: [PATCH] fix: Pin playwright to base image version in `uv` Dockerfile template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The uv branch previously kept whatever playwright version happened to be in the env after `uv sync`, which can drift from the version baked into the Apify base image — so the actor would look for a Chromium build that `/pw-browsers/` doesn't ship. Snapshot the base image's playwright version before `COPY`/`uv sync` and pin to it afterwards (mirroring the existing sed-rewrite the pip and poetry branches use). --- .../{{cookiecutter.project_name}}/Dockerfile | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile b/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile index 4f958871e2..79ef82732f 100644 --- a/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile +++ b/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile @@ -41,8 +41,11 @@ RUN echo "Python version:" \ && echo "All installed Python packages:" \ && pip freeze # % elif cookiecutter.package_manager == 'uv' +# Snapshot the base image's playwright version before COPY/uv sync so we can pin to it later +# and stay aligned with the browser binaries baked into /pw-browsers. RUN pip install -U pip setuptools \ - && pip install 'uv<1' + && pip install 'uv<1' \ + && (hash playwright 2>/dev/null && playwright --version | cut -d ' ' -f 2 > /tmp/.base-playwright-version || true) ENV UV_PROJECT_ENVIRONMENT="/usr/local" @@ -51,15 +54,20 @@ COPY pyproject.toml uv.lock ./ RUN echo "Python version:" \ && python --version \ && echo "Installing dependencies:" \ - # Check if playwright is already installed - && PLAYWRIGHT_INSTALLED=$(pip freeze | grep -q playwright && echo "true" || echo "false") \ - && if [ "$PLAYWRIGHT_INSTALLED" = "true" ]; then \ - echo "Playwright already installed, excluding from uv sync" \ - && uv sync --frozen --no-install-project --no-editable -q --no-dev --inexact --no-install-package playwright; \ + && PLAYWRIGHT_BASE_VERSION=$(cat /tmp/.base-playwright-version 2>/dev/null || echo "") \ + && if [ -n "$PLAYWRIGHT_BASE_VERSION" ]; then \ + echo "Playwright $PLAYWRIGHT_BASE_VERSION pre-installed in base image; excluding from uv sync" \ + && uv sync --frozen --no-install-project --no-editable -q --no-dev --inexact --no-install-package playwright \ + && CURRENT_PLAYWRIGHT_VERSION=$(playwright --version 2>/dev/null | cut -d ' ' -f 2) \ + && if [ "$CURRENT_PLAYWRIGHT_VERSION" != "$PLAYWRIGHT_BASE_VERSION" ]; then \ + echo "Pinning playwright back to $PLAYWRIGHT_BASE_VERSION (was $CURRENT_PLAYWRIGHT_VERSION) to match shipped browsers" \ + && uv pip install --reinstall --no-deps "playwright==$PLAYWRIGHT_BASE_VERSION"; \ + fi; \ else \ - echo "Playwright not found, installing all dependencies" \ + echo "Playwright not found in base image, installing all dependencies as resolved in the lockfile" \ && uv sync --frozen --no-install-project --no-editable -q --no-dev --inexact; \ fi \ + && rm -f /tmp/.base-playwright-version \ && echo "All installed Python packages:" \ && pip freeze # % elif cookiecutter.package_manager == 'pip'