From 54cb04136e40b7e69ba92967894974afdfe4be52 Mon Sep 17 00:00:00 2001 From: Paulo Date: Wed, 14 Oct 2026 19:28:05 +0200 Subject: [PATCH] Build the browser template on any docker base image Drukbox builds browser.sh on the default image of its docker provider, and the deployment sets that image. A compose install leaves drukbox's stock image there, which has no Node and no druks user, so npm install exited 127. A deployment can also set the sandbox image, which has both. browser.sh installs Node 22 from nodesource and adds the druks user again. Both steps also pass on the sandbox image: gpg overwrites the nodesource keyring, and useradd runs only when the user is missing. The browser PR check builds browser.sh on both images. --- .github/workflows/on-pull-request-images.yml | 13 ++++++++++--- backend/druks/browser/sandboxes/browser.sh | 12 +++++++++--- backend/druks/browser/sandboxes/goss.yaml | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/workflows/on-pull-request-images.yml b/.github/workflows/on-pull-request-images.yml index 37d540ed..dbb5379c 100644 --- a/.github/workflows/on-pull-request-images.yml +++ b/.github/workflows/on-pull-request-images.yml @@ -87,20 +87,27 @@ jobs: docker exec sbx-boot /usr/sbin/sshd -T | grep -iEx 'permitrootlogin (prohibit-password|without-password|yes)' # Drukbox builds the browser as a template: browser.sh run on the default - # image of its docker provider, which every druks deploy sets to the sandbox - # image above. + # image of its docker provider. The deployment sets that image, so browser.sh + # must build on drukbox's stock image and on the sandbox image above. browser: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + base: [ghcr.io/czpython/drukbox/sandbox:latest, druks-sandbox:pr] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Build the sandbox image + if: matrix.base == 'druks-sandbox:pr' run: docker build --target sandbox --tag druks-sandbox:pr deploy/sandbox - name: Build browser.sh the way Drukbox builds a template + env: + BASE: ${{ matrix.base }} run: | printf '%s\n' \ - 'FROM druks-sandbox:pr' \ + "FROM $BASE" \ 'COPY browser.sh /drukbox-setup.sh' \ 'RUN sh /drukbox-setup.sh && rm /drukbox-setup.sh' \ | docker build --tag druks-browser:pr --file - backend/druks/browser/sandboxes diff --git a/backend/druks/browser/sandboxes/browser.sh b/backend/druks/browser/sandboxes/browser.sh index a72ecc99..fb4a9be5 100644 --- a/backend/druks/browser/sandboxes/browser.sh +++ b/backend/druks/browser/sandboxes/browser.sh @@ -1,6 +1,7 @@ #!/bin/sh -# Drukbox builds this as root on the default image of its docker provider: the -# sandbox image (deploy/sandbox/Dockerfile), which has Node 22 and the druks user. +# Drukbox builds this as root on the default image of its docker provider. The +# deployment sets that image. It can be the sandbox image +# (deploy/sandbox/Dockerfile), which already has Node 22 and the druks user. set -eu export DEBIAN_FRONTEND=noninteractive arch="$(dpkg --print-architecture)" @@ -10,6 +11,10 @@ playwright_version=1.62.0 apt-get update apt-get install -y --no-install-recommends ca-certificates curl gnupg install -d -m 0755 /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ + | gpg --yes --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [arch=$arch signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" \ + > /etc/apt/sources.list.d/nodesource.list # Real Google Chrome, so the login browser presents Chrome's fingerprint and not # Chromium's. A login gate reads the difference. curl -fsSL https://dl.google.com/linux/linux_signing_key.pub \ @@ -19,7 +24,7 @@ echo "deb [arch=$arch signed-by=/etc/apt/keyrings/google-chrome.gpg] https://dl. apt-get update apt-get install -y --no-install-recommends \ fonts-liberation fonts-noto-cjk fonts-noto-color-emoji \ - google-chrome-stable tzdata x11vnc xvfb + google-chrome-stable nodejs tzdata x11vnc xvfb rm -rf /var/lib/apt/lists/* install -d -m 0755 /opt/druks-browser @@ -41,6 +46,7 @@ install -d -m 0755 /etc/opt/chrome/policies/managed echo '{"CommandLineFlagSecurityWarningsEnabled": false}' \ > /etc/opt/chrome/policies/managed/druks.json +id druks >/dev/null 2>&1 || useradd --create-home --shell /bin/bash druks install -d -m 0700 -o druks -g druks /work/session # Xvfb runs as druks and cannot make this directory sticky itself. install -d -m 1777 /tmp/.X11-unix diff --git a/backend/druks/browser/sandboxes/goss.yaml b/backend/druks/browser/sandboxes/goss.yaml index 27893350..02590aaa 100644 --- a/backend/druks/browser/sandboxes/goss.yaml +++ b/backend/druks/browser/sandboxes/goss.yaml @@ -1,5 +1,5 @@ # The boot contract of the browser template: the drukbox base entrypoint seeds -# the ``druks`` user of the sandbox image, and /work/session belongs to it. +# the ``druks`` user, and /work/session belongs to it. # dgoss checks it in CI with DRUKBOX_SSH_USER=druks and # DRUKBOX_AUTHORIZED_KEY="ssh-ed25519 AAAA goss". file: