diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d775a2b8d1..6e2cbe0b5a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -202,6 +202,24 @@ jobs: username: ${{ github.repository_owner }} password: ${{ github.token }} + # Persist the Dockerfile builder's yarn cache mount across runs. The mount + # (holding downloaded + compiled git deps) is not part of the image layer + # cache, so buildkit-cache-dance saves/restores it via actions/cache. + - name: Restore Docker yarn cache + id: docker-yarn-cache + uses: actions/cache@v4 + with: + path: docker-yarn-cache + key: ${{ runner.os }}-docker-yarn-cache-${{ hashFiles('yarn.lock') }} + - name: Inject yarn cache into buildx + uses: reproducible-containers/buildkit-cache-dance@v3.1.2 + with: + cache-map: | + { + "docker-yarn-cache": "/root/.yarn-cache" + } + skip-extraction: ${{ steps.docker-yarn-cache.outputs.cache-hit }} + - name: Build and push cloudserver image uses: docker/build-push-action@v5 with: diff --git a/Dockerfile b/Dockerfile index 4124f69fc8..b71858fe8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7 + ARG NODE_VERSION=22.14.0-bookworm-slim FROM node:${NODE_VERSION} AS builder @@ -22,12 +24,20 @@ RUN apt-get update \ && ssh-keyscan -H github.com > /root/ssh/known_hosts ENV PYTHON=python3 +# Persist yarn's cache in a fixed location so it can be mounted as a BuildKit +# cache below; this cache also holds the compiled git dependencies (e.g. +# arsenal's tsc output), so a warm cache skips the re-clone and re-compile. +ENV YARN_CACHE_FOLDER=/root/.yarn-cache RUN npm install -g \ node-gyp \ typescript@4.9.5 COPY package.json yarn.lock /usr/src/app/ -RUN yarn install --production --ignore-optional --frozen-lockfile --ignore-engines --network-concurrency 1 +# BuildKit cache mount: even when this layer misses (e.g. yarn.lock changed), +# yarn reuses already-downloaded and already-built packages from the mount +# instead of re-cloning and re-running tsc for the git dependencies. +RUN --mount=type=cache,target=/root/.yarn-cache,sharing=locked \ + yarn install --production --ignore-optional --frozen-lockfile --ignore-engines --network-concurrency 1 ################################################################################ FROM node:${NODE_VERSION} AS production