Some checks failed
Docker image / build-and-push-image (push) Has been cancelled
Three correctness fixes to the nix derivation that mirror the Dockerfile
correctness fixes:
1. Drop `pnpm prune --prod --ignore-scripts` from the build phase. The
prune step removed the prisma CLI (devDependency) from the output,
so the runtime invocation of `prisma migrate deploy` had nothing to
exec. Same trap the upstream Dockerfile fell into via `--prod` install.
2. Copy `scripts/` into `$out/share/nsecbunkerd/` alongside dist,
node_modules, prisma, templates. Without it the launcher script
(which contains the migration step) wasn't present.
3. The makeWrapper target switches from `dist/index.js` to
`scripts/start.js`. Same change the Dockerfile ENTRYPOINT got in
the previous commit. Also adds nodejs_20 to PATH so `npm` is
resolvable from inside start.js, and drops `--chdir` so the caller
(systemd, docker compose) controls cwd — start.js now resolves
sibling paths from `__dirname`, independently committed.
The `patchNdk` substitution narrows from the old `workspace:*` form
(no longer in the package.json after fork commit 06272c8) to the
current `"2.8.1"` → `"^2.8.1"` rewrite needed to align package.json
with the lockfile under --frozen-lockfile.
Remaining known gap: nixpkgs ships prisma-engines 7.7.0 while the
JS prisma CLI in node_modules is 5.4.1, an RPC vocabulary mismatch
that breaks the migrate step at runtime (`Method not found:
listMigrationDirectories`). Either bump prisma JS to ^7.x or overlay
prisma-engines to 5.4.1. Out of scope for this commit; docker build
unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
143 lines
4.5 KiB
Nix
143 lines
4.5 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
pnpm_8,
|
|
nodejs_20,
|
|
makeWrapper,
|
|
prisma-engines,
|
|
openssl,
|
|
sqlite,
|
|
python311,
|
|
pkg-config,
|
|
node-gyp,
|
|
}:
|
|
|
|
let
|
|
# Fork commit `06272c8` ("pin @nostr-dev-kit/ndk to 2.8.1 instead of
|
|
# workspace:*") changed package.json to a pinned `"2.8.1"`, but the
|
|
# pnpm-lock.yaml still expresses the spec as `"^2.8.1"` (the way
|
|
# `pnpm add` originally generated it). pnpm with --frozen-lockfile
|
|
# rejects that mismatch. Patching package.json to use the caret form
|
|
# is non-semantic (2.8.1 is still the resolved version) and aligns
|
|
# both files. Same fix the Dockerfile-side already handles via
|
|
# `--no-frozen-lockfile`; in nix we prefer frozen + a targeted patch.
|
|
patchNdk = ''
|
|
substituteInPlace package.json \
|
|
--replace-fail '"@nostr-dev-kit/ndk": "2.8.1"' \
|
|
'"@nostr-dev-kit/ndk": "^2.8.1"'
|
|
'';
|
|
|
|
prismaEnv = {
|
|
PRISMA_SCHEMA_ENGINE_BINARY = lib.getExe' prisma-engines "schema-engine";
|
|
PRISMA_QUERY_ENGINE_BINARY = lib.getExe' prisma-engines "query-engine";
|
|
PRISMA_QUERY_ENGINE_LIBRARY = "${prisma-engines}/lib/libquery_engine.node";
|
|
PRISMA_INTROSPECTION_ENGINE_BINARY = lib.getExe' prisma-engines "introspection-engine";
|
|
PRISMA_FMT_BINARY = lib.getExe' prisma-engines "prisma-fmt";
|
|
PRISMA_CLIENT_ENGINE_TYPE = "binary";
|
|
};
|
|
in
|
|
stdenv.mkDerivation (finalAttrs: {
|
|
pname = "nsecbunkerd";
|
|
version = "0.10.5";
|
|
|
|
src = ./.;
|
|
|
|
pnpmDeps = pnpm_8.fetchDeps {
|
|
inherit (finalAttrs) pname version src;
|
|
fetcherVersion = 2;
|
|
prePnpmInstall = patchNdk;
|
|
hash = "sha256-dQ+TX5jf1ZQKGoPCZgWaFwpAC3uP6iL1ZSxS0mFNdP8=";
|
|
};
|
|
|
|
postPatch = patchNdk;
|
|
|
|
nativeBuildInputs = [
|
|
pnpm_8.configHook
|
|
pnpm_8
|
|
nodejs_20
|
|
makeWrapper
|
|
node-gyp
|
|
python311
|
|
pkg-config
|
|
];
|
|
|
|
buildInputs = [
|
|
openssl
|
|
sqlite
|
|
];
|
|
|
|
env = prismaEnv;
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
|
|
export npm_config_nodedir=${nodejs_20}
|
|
pnpm config set nodedir ${nodejs_20}
|
|
|
|
# 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
|
|
|
|
pnpm prisma generate
|
|
pnpm build
|
|
|
|
# Do NOT `pnpm prune --prod` here — the prisma CLI lives in
|
|
# devDependencies and `scripts/start.js` invokes it at boot via
|
|
# `npx prisma migrate deploy`. Without the CLI, the migration step
|
|
# silently fails (npx falls back to downloading prisma fresh, which
|
|
# OOMs on most containers) and the SQLite db stays empty. See
|
|
# `aiolabs/nsecbunkerd#7` diagnosis 2026-05-27.
|
|
find node_modules -xtype l -delete
|
|
|
|
runHook postBuild
|
|
'';
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
|
|
mkdir -p $out/{bin,share/nsecbunkerd}
|
|
# scripts/ MUST be copied — it contains the start.js launcher that
|
|
# runs `prisma migrate deploy` before spawning the daemon. The
|
|
# upstream packaging (and the upstream Dockerfile) bypassed this by
|
|
# invoking dist/index.js directly, leaving migrations unapplied.
|
|
cp -r dist node_modules prisma scripts templates package.json \
|
|
$out/share/nsecbunkerd/
|
|
|
|
# Wrapper invokes scripts/start.js, which runs `prisma migrate deploy`
|
|
# then spawns dist/index.js. start.js resolves sibling paths from
|
|
# __dirname, so the caller (systemd unit, docker compose, etc.) can
|
|
# set its own WorkingDirectory for the writable state dir without
|
|
# interfering with how the launcher finds its own package files.
|
|
# NSEC_BUNKER_CONFIG_DIR can override the config directory location;
|
|
# by default it's `./config` relative to cwd.
|
|
makeWrapper ${lib.getExe nodejs_20} $out/bin/nsecbunkerd \
|
|
--add-flags $out/share/nsecbunkerd/scripts/start.js \
|
|
--set NODE_ENV production \
|
|
--prefix PATH : ${lib.makeBinPath [ openssl nodejs_20 ]} \
|
|
${
|
|
lib.concatStringsSep " \\\n " (
|
|
lib.mapAttrsToList (n: v: "--set ${n} ${lib.escapeShellArg v}") prismaEnv
|
|
)
|
|
}
|
|
|
|
makeWrapper ${lib.getExe nodejs_20} $out/bin/nsecbunker-client \
|
|
--chdir $out/share/nsecbunkerd \
|
|
--add-flags $out/share/nsecbunkerd/dist/client/client.js \
|
|
--set NODE_ENV production
|
|
|
|
runHook postInstall
|
|
'';
|
|
|
|
passthru = {
|
|
inherit prisma-engines;
|
|
};
|
|
|
|
meta = {
|
|
description = "Nostr remote signing daemon (NIP-46)";
|
|
homepage = "https://github.com/kind-0/nsecbunkerd";
|
|
license = lib.licenses.mit;
|
|
mainProgram = "nsecbunkerd";
|
|
platforms = lib.platforms.linux;
|
|
};
|
|
})
|