44 lines
2.1 KiB
Docker
44 lines
2.1 KiB
Docker
# 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
|