diff --git a/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile b/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile index 137780e0df..dcab0ea94c 100644 --- a/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile +++ b/src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile @@ -1,19 +1,26 @@ # First, specify the base Docker image. # You can see the Docker images from Apify at https://hub.docker.com/r/apify/. # You can also use any other image from Docker Hub. + +{# The Playwright version baked into the Apify Playwright base images. Keep this in sync with the + `playwright` version resolved by the lockfile so the installed package matches the browser + binaries shipped in the base image. #} +# % set playwright_version = '1.60.0' + # % if cookiecutter.crawler_type == 'playwright' or cookiecutter.crawler_type.startswith('adaptive-') or cookiecutter.crawler_type == 'stagehand' -# % set base_image = 'apify/actor-python-playwright:3.13-1.60.0' +# % set base_image = 'apify/actor-python-playwright:3.13-' ~ playwright_version # % elif cookiecutter.crawler_type == 'playwright-camoufox' -# % set base_image = 'apify/actor-python-playwright-camoufox:3.13-1.60.0' +# % set base_image = 'apify/actor-python-playwright-camoufox:3.13-' ~ playwright_version # % elif cookiecutter.crawler_type == 'playwright-chrome' -# % set base_image = 'apify/actor-python-playwright-chrome:3.13-1.60.0' +# % set base_image = 'apify/actor-python-playwright-chrome:3.13-' ~ playwright_version # % elif cookiecutter.crawler_type == 'playwright-firefox' -# % set base_image = 'apify/actor-python-playwright-firefox:3.13-1.60.0' +# % set base_image = 'apify/actor-python-playwright-firefox:3.13-' ~ playwright_version # % elif cookiecutter.crawler_type == 'playwright-webkit' -# % set base_image = 'apify/actor-python-playwright-webkit:3.13-1.60.0' +# % set base_image = 'apify/actor-python-playwright-webkit:3.13-' ~ playwright_version # % else # % set base_image = 'apify/actor-python:3.13' # % endif +# % set uses_playwright_base_image = 'playwright' in base_image FROM {{ base_image }} RUN apt update && apt install -yq git && rm -rf /var/lib/apt/lists/* @@ -32,21 +39,18 @@ COPY pyproject.toml poetry.lock ./ RUN echo "Python version:" \ && python --version \ && echo "Installing dependencies:" \ - # Export packages from poetry.lock - && poetry export -f requirements.txt --without-hashes | \ - # Replace playwright version so that it matches whatever is pre-installed in the image (the `hash` checks if playwright is installed) - sed "s/^playwright==\(.*\)/playwright==$(hash playwright 2>/dev/null && (playwright --version | cut -d ' ' -f 2) || echo '\1')/" | \ - # Install everything using pip (ignore dependency checks - the lockfile is correct, period) - pip install -r /dev/stdin --no-dependencies \ + # Export packages from poetry.lock and install everything using pip + # (ignore dependency checks - the lockfile is correct, period) + && poetry export -f requirements.txt --without-hashes | pip install -r /dev/stdin --no-dependencies \ && echo "All installed Python packages:" \ && pip freeze +# % if uses_playwright_base_image +# Pin playwright to the version baked into the base image so it matches the browser binaries. +RUN pip install --no-deps --force-reinstall "playwright=={{ playwright_version }}" +# % endif # % elif cookiecutter.package_manager == 'uv' COPY --from=ghcr.io/astral-sh/uv:0.11 /uv /uvx /bin/ -# Snapshot the base image's playwright version before uv sync so we can pin to it later -# and stay aligned with the browser binaries baked into /pw-browsers. -RUN hash playwright 2>/dev/null && playwright --version | cut -d ' ' -f 2 > /tmp/.base-playwright-version || true - ENV UV_PROJECT_ENVIRONMENT="/usr/local" COPY pyproject.toml uv.lock ./ @@ -55,14 +59,12 @@ RUN echo "Python version:" \ && python --version \ && echo "Installing dependencies:" \ && uv sync --frozen --no-install-project --no-editable --quiet --no-dev --inexact \ - && PLAYWRIGHT_BASE_VERSION=$(cat /tmp/.base-playwright-version 2>/dev/null || echo "") \ - && if [ -n "$PLAYWRIGHT_BASE_VERSION" ]; then \ - echo "Pinning playwright to $PLAYWRIGHT_BASE_VERSION to match the browser binaries shipped in the base image" \ - && uv pip install --system --reinstall --no-deps "playwright==$PLAYWRIGHT_BASE_VERSION"; \ - fi \ - && rm -f /tmp/.base-playwright-version \ && echo "All installed Python packages:" \ && pip freeze +# % if uses_playwright_base_image +# Pin playwright to the version baked into the base image so it matches the browser binaries. +RUN uv pip install --system --reinstall --no-deps "playwright=={{ playwright_version }}" +# % endif # % elif cookiecutter.package_manager == 'pip' RUN pip install -U pip setuptools @@ -75,14 +77,13 @@ COPY requirements.txt ./ RUN echo "Python version:" \ && python --version \ && echo "Installing dependencies:" \ - # Install everything using pip, set playwright version so that it matches whatever is pre-installed in the image - && cat requirements.txt | \ - # Replace playwright version so that it matches whatever is pre-installed in the image (the `hash` checks if playwright is installed) - sed "s/^playwright==\(.*\)/playwright==$(hash playwright 2>/dev/null && (playwright --version | cut -d ' ' -f 2) || echo '\1')/" | \ - # Install everything using pip - pip install -r /dev/stdin \ + && pip install -r requirements.txt \ && echo "All installed Python packages:" \ && pip freeze +# % if uses_playwright_base_image +# Pin playwright to the version baked into the base image so it matches the browser binaries. +RUN pip install --no-deps --force-reinstall "playwright=={{ playwright_version }}" +# % endif # % elif cookiecutter.package_manager == 'manual' # TODO install dependencies # % endif