From 36f84941db7728ef8f4cd27f330169d041462d95 Mon Sep 17 00:00:00 2001 From: Roland Date: Thu, 23 Jul 2026 18:10:52 -0600 Subject: [PATCH] install: always install serve; resolve it via PATH in wrolpi-app wrolpi-app crash-loops with 203/EXEC when /usr/local/bin/serve is missing. Two independent causes, both fixed here: 1. The `single-file --version ||` guard in the install scripts only installed serve (and readability) when single-file was ABSENT. On a machine that already has single-file (a prior install or a baked image), serve was skipped, and re-running install.sh could never repair it. Install each npm global independently based on its own presence. 2. The service hardcoded /usr/local/bin/serve, which breaks when npm's global prefix puts serve in /usr/bin (depends on how node was installed). Resolve serve via PATH with `/usr/bin/env serve`. Verified on a fresh Raspberry Pi OS Trixie install (10.0.0.8): wrolpi-app is active with 0 restarts and serves 200 with the PATH-resolved ExecStart. Co-Authored-By: Claude Opus 4.8 (1M context) --- etc/raspberrypios/wrolpi-app.service | 4 +++- scripts/install_debian_12.sh | 7 +++++-- scripts/install_raspberrypios.sh | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/etc/raspberrypios/wrolpi-app.service b/etc/raspberrypios/wrolpi-app.service index b9dd0e98..9cf447c9 100644 --- a/etc/raspberrypios/wrolpi-app.service +++ b/etc/raspberrypios/wrolpi-app.service @@ -6,7 +6,9 @@ Conflicts=wrolpi-app-dev.service [Service] # Use explicit `serve.json` so `epub.html` is not lost. -ExecStart=/usr/local/bin/serve build -l 3000 -c /opt/wrolpi/app/serve.json +# Resolve `serve` via PATH so it works regardless of npm's global prefix +# (/usr/local/bin vs /usr/bin depending on how node was installed). +ExecStart=/usr/bin/env serve build -l 3000 -c /opt/wrolpi/app/serve.json Group=wrolpi User=wrolpi WorkingDirectory=/opt/wrolpi/app/ diff --git a/scripts/install_debian_12.sh b/scripts/install_debian_12.sh index 7ae2f5ec..23d43379 100755 --- a/scripts/install_debian_12.sh +++ b/scripts/install_debian_12.sh @@ -20,8 +20,11 @@ apt-get install -y $(cat /opt/wrolpi/debian-live-config/config/package-lists/wro node -v npm -v -# Install serve, and archiving tools. -single-file --version || sudo npm i -g serve@12.0.1 single-file-cli@2.0.73 readability-extractor@0.0.6 +# Install serve, and archiving tools. Check each independently so a present +# single-file cannot mask a missing serve (which breaks wrolpi-app). +command -v serve >/dev/null || sudo npm i -g serve@12.0.1 +single-file --version >/dev/null 2>&1 || sudo npm i -g single-file-cli@2.0.73 +command -v readability-extractor >/dev/null || sudo npm i -g readability-extractor@0.0.6 # Install Deno runtime; single-file runs under it. command -v deno || { diff --git a/scripts/install_raspberrypios.sh b/scripts/install_raspberrypios.sh index 0c7e2ece..3e005676 100755 --- a/scripts/install_raspberrypios.sh +++ b/scripts/install_raspberrypios.sh @@ -20,8 +20,11 @@ apt-get install -y $(cat /opt/wrolpi/pi-gen/stage2/04-wrolpi/01-packages-nr) node -v npm -v -# Install serve, and archiving tools. -single-file --version || sudo npm i -g serve@12.0.1 single-file-cli@2.0.73 readability-extractor@0.0.6 +# Install serve, and archiving tools. Check each independently so a present +# single-file cannot mask a missing serve (which breaks wrolpi-app). +command -v serve >/dev/null || sudo npm i -g serve@12.0.1 +single-file --version >/dev/null 2>&1 || sudo npm i -g single-file-cli@2.0.73 +command -v readability-extractor >/dev/null || sudo npm i -g readability-extractor@0.0.6 # Install Deno runtime; single-file runs under it. command -v deno || {