fix(docker): install Node/npm at runtime for npm-based CLI Apps#7
Merged
Conversation
npm-based CLI Apps (e.g. hyperframes) failed to install from the WebUI
with a 400 "npm is not installed". The runtime image is Python-only —
Node/npm lived solely in the discarded webui-builder stage — so the
install path's shutil.which("npm") returned None and raised CliAppError.
Copy Node + npm from the webui-builder stage into the runtime image and
route `npm install -g` to a user-writable prefix (/home/nanobot/.npm-global)
on PATH, so installs succeed as the non-root nanobot user and the
resulting CLI resolves via shutil.which(entry_point).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Installing an npm-based CLI App (e.g. hyperframes) from the WebUI failed with:
Root cause
The runtime image (
ghcr.io/astral-sh/uv:python3.12-bookworm-slim) is Python-only. Node/npm existed only in the discardedwebui-builderstage, so at runtimeshutil.which("npm")innanobot/apps/cli/service.pyreturnedNoneand raisedCliAppError("npm is not installed")— which defaults to HTTP 400.A second latent issue: the gateway runs as the non-root
nanobotuser, andnpm install -gdefaults to/usr/local, which that user can't write to (EACCES).Fix
webui-builderstage into the runtime image (reuses the toolchain already in the build — no second download).npm install -gto a user-writable prefix (/home/nanobot/.npm-global) and put itsbin/onPATH, so installs succeed asnanobotand the installed CLI resolves viashutil.which(entry_point).Verification
Built the image and ran the exact registry command as the
nanobotuser:Both
node --version/npm --versionalso run as a build-time check.Notes
.npm-globallives in the image home, not the mounted disk, so npm-installed CLIs are ephemeral across redeploys (same as the existing pip apps). Can be moved onto the disk in a follow-up if persistence is desired.🤖 Generated with Claude Code