From 8d0670a637d87bef843d31a7e4869198994fbbf8 Mon Sep 17 00:00:00 2001 From: Sylvain Duchesne Date: Mon, 19 Oct 2026 16:44:09 +0200 Subject: [PATCH] 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. --- backend/Dockerfile | 11 ++++++++++- backend/package.json | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 7ca0be1..3861532 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -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 diff --git a/backend/package.json b/backend/package.json index e90db65..5591654 100644 --- a/backend/package.json +++ b/backend/package.json @@ -34,5 +34,12 @@ "engines": { "node": ">=22.12" }, + "pnpm": { + "onlyBuiltDependencies": [ + "bcrypt", + "sharp", + "sodium-native" + ] + }, "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402" }