Merge pull request 'fix(nix): build bcrypt's native binding again under pnpm 10 — unbreaks nsecbunkerd on aio-demo' (#54) from fix/pnpm10-bcrypt-native-build into dev
Some checks failed
Docker image / build-and-push-image (push) Has been cancelled

Reviewed-on: #54
This commit is contained in:
padreug 2026-09-05 19:00:01 +00:00
commit c20d053cd1

View file

@ -9,6 +9,9 @@
# 7.x in nixpkgs which doesn't ship libquery_engine.node, so we'd fail
# at postinstall.
prisma-engines_6,
bash,
coreutils,
gnused,
openssl,
sqlite,
python311,
@ -80,7 +83,21 @@ stdenv.mkDerivation (finalAttrs: {
# configHook ran with --ignore-scripts; re-run install to trigger
# native-module postinstall (bcrypt). --offline keeps it inside the
# store seeded by configHook.
pnpm install --force --offline --frozen-lockfile --reporter=append-only
#
# `dangerouslyAllowAllBuilds` is load-bearing under pnpm 10: unlike
# pnpm 9, pnpm 10 refuses to run *any* dependency lifecycle script
# unless the package is allow-listed (`onlyBuiltDependencies` /
# `pnpm approve-builds`), and it skips them **silently** — the install
# still reports success. Without this, bcrypt's node-gyp postinstall
# never runs, `lib/binding/napi-v3/bcrypt_lib.node` is never produced,
# and the daemon dies at boot with MODULE_NOT_FOUND. That is exactly
# what shipped in 0d8c436 (the nodejs_20/pnpm_9 -> nodejs_24/pnpm_10
# bump) and took down nsecbunkerd on aio-demo. The flag restores the
# pnpm 9 semantics this build has always relied on; we are inside the
# nix sandbox against a store-seeded offline cache, so "all builds"
# is the same closed set of scripts pnpm 9 ran.
pnpm install --force --offline --frozen-lockfile --reporter=append-only \
--config.dangerouslyAllowAllBuilds=true
pnpm prisma generate
pnpm build
@ -117,7 +134,22 @@ stdenv.mkDerivation (finalAttrs: {
makeWrapper ${lib.getExe nodejs_24} $out/bin/nsecbunkerd \
--add-flags $out/share/nsecbunkerd/scripts/start.js \
--set NODE_ENV production \
--prefix PATH : ${lib.makeBinPath [ openssl nodejs_24 ]} \
--prefix PATH : ${
lib.makeBinPath [
openssl
nodejs_24
# scripts/start.js shells out to `npm run prisma:migrate`, and
# npm needs a shell to spawn at all. The pnpm-generated
# `node_modules/.bin/prisma` shim is itself a /bin/sh script
# that resolves its basedir with `dirname` + `sed`. Ship all
# three so the launcher works under any caller's environment
# (the systemd unit's PATH, docker compose, a bare shell)
# rather than depending on what the caller happens to export.
bash
coreutils
gnused
]
} \
${
lib.concatStringsSep " \\\n " (
lib.mapAttrsToList (n: v: "--set ${n} ${lib.escapeShellArg v}") prismaEnv
@ -132,6 +164,22 @@ stdenv.mkDerivation (finalAttrs: {
runHook postInstall
'';
doInstallCheck = true;
# The bcrypt failure mode is silent at build time and fatal at boot, so
# assert the native binding loads from the *installed* tree exactly the
# way `dist/daemon/index.js` loads it. A build that can't require bcrypt
# must fail here rather than on the deployed host.
installCheckPhase = ''
runHook preInstallCheck
${lib.getExe nodejs_24} -e \
"require('$out/share/nsecbunkerd/node_modules/bcrypt'); \
console.log('bcrypt native binding loads OK')"
runHook postInstallCheck
'';
passthru = {
inherit prisma-engines;
};