scanservjs: package the backend with the frontend

scanservjs has been ignoring the configuration options set by the NixOS
module since the v3.0.4 upgrade. This fixes it.

Create dirs/files in the NixOS module as needed by the new scanservjs
build.

Fixes: 7432e50d62 ("scanservjs: 2.27.1 -> 3.0.4")
Fixes: https://github.com/NixOS/nixpkgs/issues/475043 ("nixos/scanservjs: settings (host/port) ignored in v3.0.4")

Co-authored-by: Bjørn Forsman <bjorn.forsman@gmail.com>
This commit is contained in:
Ryan Horiguchi 2026-02-20 01:32:40 +01:00 committed by Bjørn Forsman
commit 008e87e5c2
4 changed files with 81 additions and 67 deletions

View file

@ -125,6 +125,12 @@ in
};
users.groups.scanservjs = { };
systemd.tmpfiles.rules = [
"d ${cfg.stateDir}/data 0755 scanservjs scanservjs - -"
"d ${cfg.stateDir}/data/preview 0755 scanservjs scanservjs - -"
"L+ ${cfg.stateDir}/data/preview/default.jpg - - - - ${package}/lib/data/preview/default.jpg"
];
systemd.services.scanservjs = {
description = "scanservjs";
after = [ "network.target" ];

View file

@ -1,64 +0,0 @@
diff --git a/packages/server/src/api.js b/packages/server/src/api.js
index bd43842..71ce7c9 100644
--- a/packages/server/src/api.js
+++ b/packages/server/src/api.js
@@ -105,7 +105,7 @@ module.exports = new class Api {
}
// If not then it's possible the default image is not quite the correct aspect ratio
- const buffer = FileInfo.create(`${config.previewDirectory}/default.jpg`).toBuffer();
+ const buffer = FileInfo.create('NIX_OUT_PLACEHOLDER/lib/node_modules/scanservjs-api/data/preview/default.jpg').toBuffer();
try {
// We need to know the correct aspect ratio from the device
diff --git a/packages/server/src/application.js b/packages/server/src/application.js
index 2771036..0c2a4c0 100644
--- a/packages/server/src/application.js
+++ b/packages/server/src/application.js
@@ -26,7 +26,7 @@ module.exports = new class Application {
userOptions() {
if (this._userOptions === null) {
- this._userOptions = new UserOptions('../../config/config.local.js');
+ this._userOptions = new UserOptions(process.env.NIX_SCANSERVJS_CONFIG_PATH);
}
return this._userOptions;
}
diff --git a/packages/server/src/classes/user-options.js b/packages/server/src/classes/user-options.js
index f129e3c..c71e754 100644
--- a/packages/server/src/classes/user-options.js
+++ b/packages/server/src/classes/user-options.js
@@ -4,7 +4,7 @@ const path = require('path');
module.exports = class UserOptions {
constructor(localConfigPath) {
if (localConfigPath) {
- const localPath = path.join(__dirname, localConfigPath);
+ const localPath = localConfigPath;
if (fs.existsSync(localPath)) {
this.local = require(localPath);
}
diff --git a/packages/server/src/configure.js b/packages/server/src/configure.js
index c9e5ed8..484949c 100644
--- a/packages/server/src/configure.js
+++ b/packages/server/src/configure.js
@@ -71,6 +71,7 @@ function initialize(rootPath) {
try {
fs.mkdirSync(config.outputDirectory, { recursive: true });
+ fs.mkdirSync(config.previewDirectory, { recursive: true });
fs.mkdirSync(config.tempDirectory, { recursive: true });
} catch (exception) {
log.warn(`Error ensuring output and temp directories exist: ${exception}`);
diff --git a/packages/server/src/server.js b/packages/server/src/server.js
index e1a9fb0..3d58d37 100644
--- a/packages/server/src/server.js
+++ b/packages/server/src/server.js
@@ -5,7 +5,7 @@ const configure = require('./configure');
const config = application.config();
const app = express();
-app.use(express.static('client'));
+app.use(express.static('@client@'));
configure(app);

View file

@ -0,0 +1,47 @@
diff --git a/app-server/src/application.js b/app-server/src/application.js
index a2c065f..2d594bf 100644
--- a/app-server/src/application.js
+++ b/app-server/src/application.js
@@ -26,7 +26,7 @@ module.exports = new class Application {
userOptions() {
if (this._userOptions === null) {
- this._userOptions = new UserOptions('../../config/config.local.js');
+ this._userOptions = new UserOptions(process.env.NIX_SCANSERVJS_CONFIG_PATH);
}
return this._userOptions;
}
diff --git a/app-server/src/classes/user-options.js b/app-server/src/classes/user-options.js
index f129e3c..c71e754 100644
--- a/app-server/src/classes/user-options.js
+++ b/app-server/src/classes/user-options.js
@@ -4,7 +4,7 @@ const path = require('path');
module.exports = class UserOptions {
constructor(localConfigPath) {
if (localConfigPath) {
- const localPath = path.join(__dirname, localConfigPath);
+ const localPath = localConfigPath;
if (fs.existsSync(localPath)) {
this.local = require(localPath);
}
diff --git a/app-server/src/express-configurer.js b/app-server/src/express-configurer.js
index 945dae2..1b456cc 100644
--- a/app-server/src/express-configurer.js
+++ b/app-server/src/express-configurer.js
@@ -166,6 +166,7 @@ module.exports = class ExpressConfigurer {
try {
fs.mkdirSync(config.outputDirectory, { recursive: true });
+ fs.mkdirSync(config.previewDirectory, { recursive: true });
fs.mkdirSync(config.thumbnailDirectory, { recursive: true });
fs.mkdirSync(config.tempDirectory, { recursive: true });
} catch (exception) {
@@ -220,7 +221,7 @@ module.exports = class ExpressConfigurer {
* @returns {ExpressConfigurer}
*/
statics() {
- this.app.use(express.static('client'));
+ this.app.use(express.static('@client@'));
return this;
}

View file

@ -18,11 +18,36 @@ buildNpmPackage (finalAttrs: {
npmDepsHash = "sha256-HIWT09G8gqSFt9CIjsjJaDRnj2GO0G6JOGeI0p4/1vw=";
postInstall = ''
mkdir $out/bin
patches = [
./nix-compatibility.patch
];
postBuild = ''
# Install runtime dependencies
npm install \
--prefix ./dist \
--offline \
--production \
--ignore-scripts
'';
installPhase = ''
runHook preInstall
rm -rf $out/lib
mkdir -p $out/lib
cp -r dist/* $out/lib
substituteInPlace "$out/lib/server/express-configurer.js" \
--replace-fail "@client@" "$out/lib/client"
mkdir -p $out/bin
makeWrapper ${lib.getExe nodejs} $out/bin/scanservjs \
--set NODE_ENV production \
--add-flags "'$out/lib/node_modules/scanservjs/app-server/src/server.js'"
--add-flags "$out/lib/server/server.js"
runHook postInstall
'';
meta = {