Example for bash and node version 22:
docker build \
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
--build-arg VCS_REF=`git rev-parse --short HEAD` \
--build-arg NODE_VERSION=`cat ./configuration/versions.json | jq '."22"' -r` \
--build-arg CHECKSUM=`cat ./configuration/checksums.json | jq '."22"' -r` \
-t panascais/node:22 \
./22Example for fish and node version 22:
docker build \
--build-arg BUILD_DATE=(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VCS_REF=(git rev-parse --short HEAD) \
--build-arg NODE_VERSION=(cat ./configuration/versions.json | jq '."22"' -r) \
--build-arg CHECKSUM=(cat ./configuration/checksums.json | jq '."22"' -r) \
-t panascais/node:22 \
./22BuildKit cache mounts reuse downloaded apk packages between builds. Only the packager stage (alpine:3.23) uses them:
RUN --mount=type=cache,id=node-apk-${TARGETARCH},sharing=locked,target=/apk/cache \
apk update --cache-dir /apk/cache \
&& apk add --cache-dir /apk/cache --cache-predownload \
...The builder stage runs on upstream node:X-alpine, which may ship apk-tools 2.x (Alpine 3.22 or older). Flags like --cache-predownload are apk-tools 3.x only, so the builder installs its two build deps with plain apk add --no-cache binutils curl instead.
Alpine 3.23 ships apk-tools 3.x, where --update / -U means --cache-max-age 0 (always refetch). Do not use it with cache mounts on the packager stage.
Cache IDs include ${TARGETARCH} so amd64 and arm64 packages do not mix during multi-platform builds. sharing=locked avoids races when matrix jobs build in parallel.
pnpm is installed via get.pnpm.io into /usr/local/bin/pnpm (Alpine-compatible). PNPM_HOME is /root/.local/share/pnpm for optional global installs; PATH prefers /usr/local/bin so the standalone CLI is not affected by store mounts in downstream builds.
This image does not cache-mount pnpm during its own build — it only downloads the standalone CLI (~few MB), so a store cache would add complexity for little gain.
Application Dockerfiles should cache installs at a separate path such as /pnpm/store, not /root/.local/share/pnpm/store. See pnpm Docker docs.
pnpm 11 images ship enableGlobalVirtualStore: false in /root/.config/pnpm/config.yaml so global installs (pnpm add -g) work with BuildKit cache mounts on the store path (see downstream ci-node).
- Silas Rech ([email protected])
- Maximilian Schagginger ([email protected])
Interested in contributing to Node? Contributions are welcome, and are accepted via pull requests. Please review these guidelines before submitting any pull requests.