# Pre-baked CI base image for Woodpecker pipelines. # # Purpose: eliminate the cold `pnpm install` that dominates every pipeline # (~731s median). This image ships the native toolchain (no per-run `apk add`) # AND a warm, content-addressable pnpm store with the dependency-tree tarballs # already fetched at build time. `pnpm fetch` only populates the store from the # lockfile — it does NOT run the native node-gyp builds (better-sqlite3, # node-pty, sqlite3, canvas, sharp); those still compile at `pnpm install`, # which is exactly why the musl toolchain stays baked into this image. A # pipeline `pnpm install --frozen-lockfile --prefer-offline` then resolves # tarballs from local hard-links (no network) and compiles natives against the # already-present toolchain, in tens of seconds instead of ~731s. # # Rebuilt only when `pnpm-lock.yaml` or this Dockerfile change # (see .woodpecker/ci-image.yml). # # Node version is intentionally pinned to 22 (Active LTS at time of writing). # The node:22 -> node:24 bump lands as a SEPARATE follow-up PR so the cache # change carries zero runtime-version variables. FROM node:22-alpine # Native toolchain required to compile node-gyp deps on musl, plus the # postgresql-client used by the test step's pg_isready readiness probe. `bash` # is baked here too — the sanitization step in ci.yml otherwise does a per-run # `apk add bash`. RUN apk add --no-cache python3 make g++ postgresql-client bash # Pin pnpm to the repo's packageManager version via corepack. RUN corepack enable && corepack prepare pnpm@10.6.2 --activate WORKDIR /app # Pin the store location so the pipeline can point `store-dir` at the same path. ENV PNPM_HOME=/root/.local/share/pnpm RUN pnpm config set store-dir /root/.local/share/pnpm/store # Warm the store. `pnpm fetch` populates the content-addressable store with the # dependency tarballs directly from the lockfile (no package.json / workspace # needed), so a baked store stays valid until the lockfile changes. Note: # `fetch` does NOT compile native modules — that happens later at `pnpm install` # in the pipeline, against the toolchain baked above. COPY pnpm-lock.yaml ./ RUN pnpm fetch --frozen-lockfile