From 806f31dc935fb5fada31ca0c72eceb62b20f2b5a Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 29 May 2026 15:40:24 +0300 Subject: [PATCH] Use `pnpm` to handle node/pnpm versions in Dockerfile (#10642) --- .github/workflows/build-submit-android.yml | 2 +- .github/workflows/build-submit-ios.yml | 2 +- .../workflows/bundle-deploy-eas-update.yml | 6 +- .github/workflows/lint.yml | 6 +- .../nightly-update-source-languages.yaml | 2 +- .github/workflows/pull-request-comment.yml | 2 +- .github/workflows/pull-request-commit.yml | 4 +- .github/workflows/verify-pnpm-lock.yml | 2 +- Dockerfile | 90 ++++++++++--------- 9 files changed, 62 insertions(+), 54 deletions(-) diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index a6a5c69d3b..2748f783ba 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -37,7 +37,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 🪛 Setup jq diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index cdc1e28c03..fd09b64577 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -37,7 +37,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 🪛 Setup jq diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 8b4bd9bc6f..f4be27b0de 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -61,7 +61,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 📷 Check fingerprint and install dependencies @@ -176,7 +176,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 🔨 Setup EAS @@ -323,7 +323,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 🔨 Setup EAS diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f6bd69878d..d7715e8ea2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -33,7 +33,7 @@ jobs: check "$f" "$v" done # ENV NODE_VERSION=X.Y.Z — Go images that nvm-install Node for the JS build stage - for f in Dockerfile Dockerfile.embedr; do + for f in Dockerfile.embedr; do v=$(grep -oE 'NODE_VERSION=[0-9]+\.[0-9]+\.[0-9]+' "$f" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | sort -u) check "$f" "$v" done @@ -45,7 +45,7 @@ jobs: - name: Install node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: pnpm install uses: Wandalen/wretry.action@master @@ -71,7 +71,7 @@ jobs: - name: Install node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: pnpm install uses: Wandalen/wretry.action@master diff --git a/.github/workflows/nightly-update-source-languages.yaml b/.github/workflows/nightly-update-source-languages.yaml index 053917fd77..4b14c65c69 100644 --- a/.github/workflows/nightly-update-source-languages.yaml +++ b/.github/workflows/nightly-update-source-languages.yaml @@ -23,7 +23,7 @@ jobs: - name: Install node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: pnpm install uses: Wandalen/wretry.action@master diff --git a/.github/workflows/pull-request-comment.yml b/.github/workflows/pull-request-comment.yml index 0f478d87d1..3b70b754ca 100644 --- a/.github/workflows/pull-request-comment.yml +++ b/.github/workflows/pull-request-comment.yml @@ -122,7 +122,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: Install dependencies diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index 4df326cd2f..722af1f000 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -33,7 +33,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: Ensure tracking relevant branches and checkout base @@ -123,7 +123,7 @@ jobs: - name: 🔧 Setup Node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json cache: pnpm - name: 📷 Check fingerprint and install dependencies diff --git a/.github/workflows/verify-pnpm-lock.yml b/.github/workflows/verify-pnpm-lock.yml index 366a4736a4..2d10b11a23 100644 --- a/.github/workflows/verify-pnpm-lock.yml +++ b/.github/workflows/verify-pnpm-lock.yml @@ -26,7 +26,7 @@ jobs: - name: Install node uses: actions/setup-node@v6 with: - node-version-file: .nvmrc + node-version-file: package.json - name: Reset pnpm-lock.yaml to base env: diff --git a/Dockerfile b/Dockerfile index d959a03292..fff191cc58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,21 @@ -FROM golang:1.26-bookworm AS build-env +# +# Stage 1: build the web bundle with pnpm. +# +# Uses the official pnpm image. Node is auto-downloaded by pnpm using the +# `devEngines.runtime` field in package.json (onFail: "download"). +# +FROM ghcr.io/pnpm/pnpm:11 AS web-build -WORKDIR /usr/src/social-app +WORKDIR /app ENV DEBIAN_FRONTEND=noninteractive # -# Node +# pnpm config # -ENV NODE_VERSION=24.15.0 -ENV NVM_DIR=/usr/share/nvm - -# -# Go -# -ENV GODEBUG="netdns=go" -ENV GOOS="linux" -ENV GOARCH="amd64" -ENV CGO_ENABLED=1 -ENV GOEXPERIMENT="loopvar" +ENV CI=1 +# use the pnpm version specified in package.json +ENV pnpm_config_pm_on_fail=download # The latest git hash of the preview branch on render.com # https://render.com/docs/docker-secrets#environment-variables-in-docker-builds @@ -42,41 +40,48 @@ ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN:-unknown} ARG EXPO_PUBLIC_SENTRY_DSN ENV EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN -# -# Copy everything into the container -# COPY . . -# -# Generate the JavaScript webpack. -# -RUN mkdir --parents $NVM_DIR && \ - wget \ - --output-document=/tmp/nvm-install.sh \ - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh && \ - bash /tmp/nvm-install.sh - -RUN \. "$NVM_DIR/nvm.sh" && \ - nvm install $NODE_VERSION && \ - nvm use $NODE_VERSION && \ - echo "Using bundle identifier: $EXPO_PUBLIC_BUNDLE_IDENTIFIER" && \ +RUN echo "Using bundle identifier: $EXPO_PUBLIC_BUNDLE_IDENTIFIER" && \ echo "EXPO_PUBLIC_ENV=$EXPO_PUBLIC_ENV" >> .env && \ echo "EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION" >> .env && \ echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER" >> .env && \ echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \ - echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env && \ - npm install --global pnpm@11.1.1 && \ - pnpm install --frozen-lockfile && \ - pnpm intl:build 2>&1 | tee i18n.log && \ - if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi && \ - SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER pnpm build-web + echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env + +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile + +RUN pnpm intl:build 2>&1 | tee i18n.log && \ + if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi + +RUN SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN \ + SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION \ + SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER \ + pnpm build-web + +# +# Stage 2: build the bskyweb Go binary, embedding the assets from stage 1. +# +# post-web-build.js (run by `pnpm build-web`) writes the bundled JS/CSS/media +# into bskyweb/static/* and regenerates bskyweb/templates/scripts.html, so +# copying the bskyweb/ tree from stage 1 is enough for go:embed to find +# everything. +# +FROM golang:1.26-bookworm AS go-build + +WORKDIR /usr/src/social-app + +ENV GODEBUG="netdns=go" +ENV GOOS="linux" +ENV GOARCH="amd64" +ENV CGO_ENABLED=1 +ENV GOEXPERIMENT="loopvar" + +COPY --from=web-build /app/bskyweb ./bskyweb # DEBUG -RUN find ./bskyweb/static && find ./web-build/static +RUN find ./bskyweb/static -# -# Generate the bskyweb Go binary. -# RUN cd bskyweb/ && \ go mod download && \ go mod verify @@ -89,6 +94,9 @@ RUN cd bskyweb/ && \ -o /bskyweb \ ./cmd/bskyweb +# +# Stage 3: runtime image. +# FROM debian:bookworm-slim ENV GODEBUG=netdns=go @@ -102,7 +110,7 @@ RUN apt-get update && apt-get install --yes \ ENTRYPOINT ["dumb-init", "--"] WORKDIR /bskyweb -COPY --from=build-env /bskyweb /usr/bin/bskyweb +COPY --from=go-build /bskyweb /usr/bin/bskyweb CMD ["/usr/bin/bskyweb"]