From cbd3b491439dfcd8cce1b5a3c3dd8298146d819f Mon Sep 17 00:00:00 2001 From: luen Date: Fri, 7 Aug 2026 10:43:50 +1000 Subject: [PATCH] Add linux/arm64 multi-arch support for ulixee-cloud Docker images. Google now publishes Chrome for linux-arm64. Switch the Docker release workflow to buildx multi-platform manifests, document arm64 requirements, and fix bookworm apt sources so the image builds again. Co-authored-by: Cursor --- .github/workflows/docker.yml | 49 +++++++++++++++++++++-------------- cloud/tools/docker/Dockerfile | 14 ++++++---- cloud/tools/docker/README.md | 15 +++++++++++ cloud/tools/docker/build.sh | 24 ++++++++++++++--- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 07975bd3f..00fa631d8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -9,9 +9,15 @@ jobs: release: name: Build latest docker release runs-on: ubuntu-latest + permissions: + contents: read + packages: write env: GITHUB_URL: https://github.com/${{ github.repository }} IMAGE: ulixee/ulixee-cloud + # linux/arm64 needs Google Chrome arm64 debs (Chrome 151+, public since + # 2026-07-30) and matching ulixee/chrome-versions linux_arm64 assets. + DOCKER_PLATFORMS: linux/amd64,linux/arm64 steps: - uses: actions/checkout@v4 @@ -35,30 +41,47 @@ jobs: PREVIOUS_CHROME_VERSION=$((CHROME_VERSION - 1)) echo "ADD_CHROME_VERSION=$PREVIOUS_CHROME_VERSION" >> $GITHUB_ENV + echo "Primary Chrome package: ${CHROME_PACKAGE} (also installing chrome-${PREVIOUS_CHROME_VERSION}-0)" + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build Image + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push multi-arch image shell: bash working-directory: cloud/tools/docker + env: + DOCKER_BUILDKIT: 1 run: | export BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - echo "Building Docker image: ${VERSION}" + echo "Building multi-arch Docker image: ${VERSION} (${DOCKER_PLATFORMS})" - docker build \ + docker buildx build \ + --platform "${DOCKER_PLATFORMS}" \ --progress auto \ - --cache-from ghcr.io/${IMAGE}:latest \ - --build-arg BUILDKIT_INLINE_CACHE=1 \ + --push \ + --cache-from type=gha \ + --cache-to type=gha,mode=max \ \ --build-arg BUILD_DATE=${BUILD_DATE} \ --build-arg GITHUB_SHA=${GITHUB_SHA} \ - --build-arg ADD_TO_INSTALL="yarn add "@ulixee/chrome-$ADD_CHROME_VERSION-0"" \ + --build-arg ADD_TO_INSTALL="yarn add @ulixee/chrome-${ADD_CHROME_VERSION}-0" \ --build-arg VERSION=${VERSION} \ \ --tag ghcr.io/${IMAGE}:v${VERSION} \ @@ -74,15 +97,3 @@ jobs: --label org.opencontainers.image.source=${GITHUB_URL} \ --label org.opencontainers.image.revision=${GITHUB_SHA} \ . - - - name: Push Image to GHCR - run: docker push -a ghcr.io/${IMAGE} - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Push Image to Dockerhub - run: docker push -a docker.io/${IMAGE} diff --git a/cloud/tools/docker/Dockerfile b/cloud/tools/docker/Dockerfile index ea14bfc97..ba1b0479c 100644 --- a/cloud/tools/docker/Dockerfile +++ b/cloud/tools/docker/Dockerfile @@ -6,11 +6,14 @@ LABEL org.opencontainers.image.source=https://github.com/ulixee/platform LABEL org.opencontainers.image.description="The open data platform. This image packages Ulixee Cloud, Hero and the last 2 Chrome versions." LABEL org.opencontainers.image.licenses=MIT -# fonts -RUN echo "deb http://deb.debian.org/debian/ buster main contrib non-free" >> /etc/apt/sources.list \ +# Fonts + Chrome/Xvfb runtime deps. Current node:*-slim images are Debian +# bookworm (DEB822 sources). Enable contrib/non-free for mscorefonts; +# fonts-wqy-zenhei replaces the removed ttf-wqy-zenhei package. +# Multi-arch: this Dockerfile is built for linux/amd64 and linux/arm64. +RUN sed -i 's/Components: main$/Components: main contrib non-free non-free-firmware/' /etc/apt/sources.list.d/debian.sources \ && echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections \ && apt-get update \ - && apt-get install -y \ + && apt-get install -y --no-install-recommends \ fonts-arphic-ukai \ fonts-arphic-uming \ fonts-ipafont-mincho \ @@ -18,12 +21,13 @@ RUN echo "deb http://deb.debian.org/debian/ buster main contrib non-free" >> /et fonts-kacst \ fonts-ipafont-gothic \ fonts-unfonts-core \ - ttf-wqy-zenhei \ + fonts-wqy-zenhei \ ttf-mscorefonts-installer \ fonts-freefont-ttf \ xvfb \ git \ curl \ + ca-certificates \ && apt-get clean \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* @@ -54,5 +58,5 @@ RUN cd /app/ulixee && yarn init -yp \ # Add below to run as unprivileged user. It's not included by default, but you can use docker run `--user ulixee`. # USER ulixee -CMD npx @ulixee/cloud start +CMD ["npx", "@ulixee/cloud", "start"] # To run this docker, please see ./run.sh diff --git a/cloud/tools/docker/README.md b/cloud/tools/docker/README.md index a3baf5c79..2994d082b 100644 --- a/cloud/tools/docker/README.md +++ b/cloud/tools/docker/README.md @@ -16,6 +16,21 @@ sudo usermod -aG docker $USER reboot ``` +## Platforms + +Published images are multi-arch manifests for: + +| Platform | Chrome | +| --- | --- | +| `linux/amd64` | Supported (existing Ulixee Chrome packages) | +| `linux/arm64` | Supported once Hero/Cloud use a Chrome major with Google `linux-arm64` debs (Chrome **151+**, publicly released 2026-07-30) and matching [`ulixee/chrome-versions`](https://github.com/ulixee/chrome-versions) `linux_arm64` release assets | + +Local multi-arch build example: + +```bash +DOCKER_PLATFORMS=linux/amd64,linux/arm64 ./build.sh +``` + ## Pull Docker image from Github Container Registry ```bash docker pull ghcr.io/ulixee/ulixee-cloud:latest diff --git a/cloud/tools/docker/build.sh b/cloud/tools/docker/build.sh index 0bf21bf6e..638a4e9f3 100755 --- a/cloud/tools/docker/build.sh +++ b/cloud/tools/docker/build.sh @@ -11,8 +11,24 @@ else ADD_TO_INSTALL="yarn add @ulixee/chrome-$ADD_CHROME_VERSION-0" fi +# Optional: DOCKER_PLATFORMS=linux/amd64,linux/arm64 for multi-arch (requires buildx + QEMU). +# linux/arm64 needs Chrome majors with Google arm64 debs (151+) and chrome-versions +# linux_arm64 release assets (see ulixee/chrome-versions). +PLATFORMS="${DOCKER_PLATFORMS:-}" -docker build -t ulixee-cloud:$VERSION -t ulixee-cloud:latest \ - --build-arg ADD_TO_INSTALL="$ADD_TO_INSTALL" \ - --build-arg VERSION="$VERSION" \ - . +if [ -n "$PLATFORMS" ]; then + echo "Building multi-arch image for: $PLATFORMS" + # Note: docker buildx cannot --load a multi-platform image into the local + # daemon. This verifies the build; use CI / --push for registry manifests. + docker buildx build \ + --platform "$PLATFORMS" \ + -t ulixee-cloud:$VERSION -t ulixee-cloud:latest \ + --build-arg ADD_TO_INSTALL="$ADD_TO_INSTALL" \ + --build-arg VERSION="$VERSION" \ + . +else + docker build -t ulixee-cloud:$VERSION -t ulixee-cloud:latest \ + --build-arg ADD_TO_INSTALL="$ADD_TO_INSTALL" \ + --build-arg VERSION="$VERSION" \ + . +fi