The backend image starts: approve the native builds, compile sharp against the system libvips

Built and run for the first time (until now the dockerized path had only been
checked with `docker compose config`): the image built, and the container
exited at start with `Cannot find module '../build/Release/sharp-linux-x64.node'`.
pnpm 10 skips dependency build scripts unless they are approved, so sharp,
bcrypt and sodium-native were installed without their binaries. A local
node_modules can carry binaries from an earlier manual build, which is how it
stayed invisible. `pnpm.onlyBuiltDependencies` now approves the three.

Approved, sharp's installer then downloaded its prebuilt libvips and binary
from GitHub, and that download timed out on every in-build attempt (3 of 3),
failing the build, while the same download from a plain container was
instantaneous. With libvips-dev installed, sharp detects a system libvips and
compiles itself instead; npm_config_nodedir points node-gyp at the headers the
image already ships. Verified with GitHub and nodejs.org blackholed: the build
passes, sharp loads against libvips 8.14.1, bcrypt falls back to compiling.

Cost: a larger image; a multi-stage build keeping only libvips42 at runtime
would drop several hundred MB.
This commit is contained in:
Sylvain Duchesne
2026-10-19 16:44:09 +02:00
parent 812844e99d
commit 8d0670a637
2 changed files with 17 additions and 1 deletions
+10 -1
View File
@@ -1,17 +1,26 @@
FROM node:22-slim
# Install pnpm and build tools required for native modules (sharp, bcrypt).
# libvips-dev: with a system libvips present, sharp compiles itself against it instead of
# downloading its prebuilt binaries from GitHub, a download that timed out on every in-build
# attempt (2026-10-19) and failed the build.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
python3 \
make \
g++ \
pkg-config \
libvips-dev \
&& rm -rf /var/lib/apt/lists/* \
&& corepack enable && corepack prepare pnpm@10.26.0 --activate
# node-gyp compiles against the headers this image already ships rather than downloading them.
ENV npm_config_nodedir=/usr/local
WORKDIR /app
# Install dependencies first to leverage Docker layer caching.
# Install dependencies first to leverage Docker layer caching. The native modules' build
# scripts only run because package.json approves them (pnpm.onlyBuiltDependencies).
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod
+7
View File
@@ -34,5 +34,12 @@
"engines": {
"node": ">=22.12"
},
"pnpm": {
"onlyBuiltDependencies": [
"bcrypt",
"sharp",
"sodium-native"
]
},
"packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402"
}