fix(nix): build bcrypt's native binding again under pnpm 10 — unbreaks nsecbunkerd on aio-demo #54

Merged
padreug merged 2 commits from fix/pnpm10-bcrypt-native-build into dev 2026-09-05 19:00:02 +00:00

2 commits

Author SHA1 Message Date
e05e184785 fix(nix): give the launcher a shell and coreutils/gnused on PATH
Some checks failed
Docker image / build-and-push-image (push) Has been cancelled
scripts/start.js shells out to `npm run prisma:migrate`, but the wrapper
only put nodejs and openssl on PATH, so npm could not spawn a shell at
all and every boot logged

  npm error syscall spawn sh
  npm error enoent spawn sh ENOENT

This was never fatal — the systemd unit's ExecStartPre already applies
migrations — but it is pure noise in the journal and it made the real
bcrypt crash harder to spot.

A shell alone is not enough: pnpm's generated node_modules/.bin/prisma
is itself a /bin/sh script that resolves its basedir with `dirname` and
`sed`. Ship bash, coreutils and gnused so the launcher stands on its own
under any caller's environment — the systemd unit's PATH, docker
compose, or a bare shell — rather than depending on what the caller
happens to export.

Verified: with PATH set to /nonexistent, the wrapper now applies all 25
migrations and starts the daemon cleanly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QBjd9Rw4ct134JH3CnLVaw
2026-09-05 20:58:26 +02:00
d2ec84a18e fix(nix): build bcrypt's native binding again under pnpm 10
0d8c436 (nodejs_20/pnpm_9 -> nodejs_24/pnpm_10) shipped a package with
no compiled bcrypt, and nsecbunkerd has been crashlooping on aio-demo
ever since: dist/daemon/index.js requires bcrypt at load, the store path
has only binding.gyp and the C++ sources under bcrypt@5.1.1, and the
daemon dies instantly with

  Cannot find module '.../bcrypt/lib/binding/napi-v3/bcrypt_lib.node'

buildPhase re-runs `pnpm install --force --offline` specifically to fire
bcrypt's node-gyp postinstall, because configHook installs with
--ignore-scripts. pnpm 10 changed that contract: it refuses to run *any*
dependency lifecycle script unless the package is allow-listed, and it
skips them silently — the install still reports success. So the bump
turned that line into a no-op, the build kept passing, and the failure
only surfaced at boot on the deployed host.

Pass --config.dangerouslyAllowAllBuilds=true to restore the pnpm 9
semantics this build has always relied on. We run inside the nix sandbox
against a store-seeded offline cache, so "all builds" is the same closed
set of scripts pnpm 9 already ran.

Add an installCheckPhase that requires bcrypt from the *installed* $out
tree, the same way the daemon does. This failure mode is invisible at
build time and fatal at boot, so it has to break the build instead of
the host.

Verified against the nixpkgs the deploy uses (da5ad661):
lib/binding/napi-v3/bcrypt_lib.node is produced, installCheck prints
"bcrypt native binding loads OK", and the daemon reaches
"nsecBunker ready to serve requests." pnpmDeps hash is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QBjd9Rw4ct134JH3CnLVaw
2026-09-05 20:58:17 +02:00