From 37b99ceb49a145f655ceb721d1e264ec28b9c454 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Mon, 15 Jun 2026 10:49:14 -0700 Subject: [PATCH 1/2] feat(docker): add Ubuntu 26.04 (Resolute Raccoon) image Adds a Dockerfile.resolute based on Ubuntu 26.04 LTS, wires it through build.sh / publish_docker.sh (new `-resolute` tag), and runs it in the docker test matrix. --- .github/workflows/test_docker.yml | 1 + utils/docker/Dockerfile.resolute | 55 +++++++++++++++++++++++++++++++ utils/docker/build.sh | 2 +- utils/docker/publish_docker.sh | 17 ++++++++-- 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 utils/docker/Dockerfile.resolute diff --git a/.github/workflows/test_docker.yml b/.github/workflows/test_docker.yml index 24ca2ab10..a70d19914 100644 --- a/.github/workflows/test_docker.yml +++ b/.github/workflows/test_docker.yml @@ -26,6 +26,7 @@ jobs: docker-image-variant: - jammy - noble + - resolute runs-on: - ubuntu-24.04 - ubuntu-24.04-arm diff --git a/utils/docker/Dockerfile.resolute b/utils/docker/Dockerfile.resolute new file mode 100644 index 000000000..e59284913 --- /dev/null +++ b/utils/docker/Dockerfile.resolute @@ -0,0 +1,55 @@ +FROM ubuntu:resolute + +ARG DEBIAN_FRONTEND=noninteractive +ARG TZ=America/Los_Angeles +ARG DOCKER_IMAGE_NAME_TEMPLATE="mcr.microsoft.com/playwright/python:v%version%-resolute" + +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + +# === INSTALL Python === + +RUN apt-get update && \ + # Install Python + apt-get install -y python3 curl && \ + # Align with upstream Python image and don't be externally managed: + # https://github.com/docker-library/python/issues/948 + rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED && \ + update-alternatives --install /usr/bin/python python /usr/bin/python3 1 && \ + curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ + python get-pip.py && \ + rm get-pip.py && \ + # Feature-parity with node.js base images. + apt-get install -y --no-install-recommends git openssh-client gpg && \ + # clean apt cache + rm -rf /var/lib/apt/lists/* && \ + # Create the pwuser + adduser pwuser + +# === BAKE BROWSERS INTO IMAGE === + +ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright + +# 1. Add tip-of-tree Playwright package to install its browsers. +# The package should be built beforehand from tip-of-tree Playwright. +COPY ./dist/*-manylinux*.whl /tmp/ + +# 2. Bake in browsers & deps. +# Browsers will be downloaded in `/ms-playwright`. +# Note: make sure to set 777 to the registry so that any user can access +# registry. +RUN mkdir /ms-playwright && \ + mkdir /ms-playwright-agent && \ + cd /ms-playwright-agent && \ + pip install virtualenv && \ + virtualenv venv && \ + . venv/bin/activate && \ + # if its amd64 then install the manylinux1_x86_64 pip package + if [ "$(uname -m)" = "x86_64" ]; then pip install /tmp/*manylinux1_x86_64*.whl; fi && \ + # if its arm64 then install the manylinux1_aarch64 pip package + if [ "$(uname -m)" = "aarch64" ]; then pip install /tmp/*manylinux_2_17_aarch64*.whl; fi && \ + playwright mark-docker-image "${DOCKER_IMAGE_NAME_TEMPLATE}" && \ + playwright install --with-deps && rm -rf /var/lib/apt/lists/* && \ + rm /tmp/*.whl && \ + rm -rf /ms-playwright-agent && \ + chmod -R 777 /ms-playwright diff --git a/utils/docker/build.sh b/utils/docker/build.sh index 98b0b0233..3ad2e2b23 100755 --- a/utils/docker/build.sh +++ b/utils/docker/build.sh @@ -3,7 +3,7 @@ set -e set +x if [[ ($1 == '--help') || ($1 == '-h') || ($1 == '') || ($2 == '') ]]; then - echo "usage: $(basename $0) {--arm64,--amd64} {jammy,noble} playwright:localbuild-noble" + echo "usage: $(basename $0) {--arm64,--amd64} {jammy,noble,resolute} playwright:localbuild-noble" echo echo "Build Playwright docker image and tag it as 'playwright:localbuild-noble'." echo "Once image is built, you can run it with" diff --git a/utils/docker/publish_docker.sh b/utils/docker/publish_docker.sh index 3af48306b..dfdb5e511 100755 --- a/utils/docker/publish_docker.sh +++ b/utils/docker/publish_docker.sh @@ -32,6 +32,11 @@ NOBLE_TAGS=( "v${PW_VERSION}-noble" ) +# Ubuntu 26.04 +RESOLUTE_TAGS=( + "v${PW_VERSION}-resolute" +) + tag_and_push() { local source="$1" local target="$2" @@ -68,8 +73,10 @@ publish_docker_images_with_arch_suffix() { TAGS=("${JAMMY_TAGS[@]}") elif [[ "$FLAVOR" == "noble" ]]; then TAGS=("${NOBLE_TAGS[@]}") + elif [[ "$FLAVOR" == "resolute" ]]; then + TAGS=("${RESOLUTE_TAGS[@]}") else - echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', or 'noble'" + echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', 'noble', or 'resolute'" exit 1 fi local ARCH="$2" @@ -94,8 +101,10 @@ publish_docker_manifest () { TAGS=("${JAMMY_TAGS[@]}") elif [[ "$FLAVOR" == "noble" ]]; then TAGS=("${NOBLE_TAGS[@]}") + elif [[ "$FLAVOR" == "resolute" ]]; then + TAGS=("${RESOLUTE_TAGS[@]}") else - echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', or 'noble'" + echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', 'noble', or 'resolute'" exit 1 fi @@ -122,3 +131,7 @@ publish_docker_manifest jammy amd64 arm64 publish_docker_images_with_arch_suffix noble amd64 publish_docker_images_with_arch_suffix noble arm64 publish_docker_manifest noble amd64 arm64 + +publish_docker_images_with_arch_suffix resolute amd64 +publish_docker_images_with_arch_suffix resolute arm64 +publish_docker_manifest resolute amd64 arm64 From 52de08a2acff0a04cb71cca4256266134a2170a8 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Mon, 15 Jun 2026 11:17:41 -0700 Subject: [PATCH 2/2] fix(docker): use useradd instead of adduser on Ubuntu 26.04 The `adduser` wrapper is no longer present in the Ubuntu 26.04 base image, so creating pwuser failed with "adduser: not found". Use the low-level `useradd` from the always-present passwd package instead. --- utils/docker/Dockerfile.resolute | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/docker/Dockerfile.resolute b/utils/docker/Dockerfile.resolute index e59284913..f6b6cf47c 100644 --- a/utils/docker/Dockerfile.resolute +++ b/utils/docker/Dockerfile.resolute @@ -24,7 +24,7 @@ RUN apt-get update && \ # clean apt cache rm -rf /var/lib/apt/lists/* && \ # Create the pwuser - adduser pwuser + useradd -m -s /bin/bash pwuser # === BAKE BROWSERS INTO IMAGE ===