From 08db5374cb823bfa61c961d6a20055ae459199e9 Mon Sep 17 00:00:00 2001 From: devsyncwrld Date: Mon, 31 Aug 2026 11:09:14 -0300 Subject: [PATCH] build: compile better-sqlite3 from source (no Node 20 prebuilt) better-sqlite3@12.11.1 ships prebuilt binaries for ABI 127/137/141/147 only; Node 20 is ABI 115, so prebuild-install falls back to node-gyp, which fails on node:20-slim for lack of python3/make/g++. Add the toolchain to the builder stage, and in the runtime stage install, use and purge it inside a single layer so the final image ships no compiler. --- Dockerfile | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ffda2ea3..df2cb07b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,6 +21,15 @@ COPY packages/web/package.json packages/web/ # Copy patches (referenced by pnpm-lock.yaml) COPY patches/ patches/ +# better-sqlite3 publishes no prebuilt binary for Node 20 (ABI 115) — its +# releases cover ABI 127/137/141/147 only — so prebuild-install falls back to +# compiling with node-gyp, which needs python3/make/g++. node:20-slim ships +# none of them. Builder stage only: the runtime stage copies the compiled +# .node and stays slim. +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 make g++ \ + && rm -rf /var/lib/apt/lists/* + # Install dependencies RUN pnpm install --frozen-lockfile @@ -39,7 +48,9 @@ FROM node:20-slim AS runtime RUN corepack enable && corepack prepare pnpm@10.34.3 --activate # Runtime deps only: ffmpeg (media processing) + gosu (drop to non-root in the -# entrypoint). No C toolchain — better-sqlite3 and sharp load prebuilt binaries. +# entrypoint). sharp is N-API (ABI-independent) and loads a prebuilt binary; +# better-sqlite3 no longer ships one for Node 20, so it is compiled below with +# a toolchain that is purged in the same layer. RUN apt-get update && \ apt-get install -y --no-install-recommends ffmpeg gosu && \ rm -rf /var/lib/apt/lists/* @@ -58,8 +69,16 @@ COPY packages/web/package.json packages/web/ # Copy patches (referenced by pnpm-lock.yaml) COPY patches/ patches/ -# Install production dependencies only (tsx is in server dependencies) -RUN pnpm install --prod --frozen-lockfile +# Install production dependencies only (tsx is in server dependencies). +# better-sqlite3 compiles from source here (no Node 20 prebuilt), so the C +# toolchain is installed, used and purged inside this single layer — the final +# image ships no compiler. +RUN apt-get update && \ + apt-get install -y --no-install-recommends python3 make g++ && \ + pnpm install --prod --frozen-lockfile && \ + apt-get purge -y python3 make g++ && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* # Copy shared source (needed at runtime since server imports types directly) COPY packages/shared/ packages/shared/