3.9 KiB
nodevm
Install Node.js through nvm, for one user, with global packages
Purpose
Installs nvm into a single user's home directory, uses it to install one pinned Node.js version under an alias, and installs a list of global npm packages for that user.
Per-user, not system-wide. Nothing is placed on the system PATH, and another
user on the same host is unaffected — which is the point: version pinning belongs
to whoever runs the app.
What This Cube Does
- Installs build dependencies with apt, as root —
build-essential,libssl-dev,libtool,cmake, and the cairo/pango/png/jpeg/vips/rsvg/pixman headers that native addons need. The package index is refreshed first: a box nobody has updated lists .deb versions the mirror has already dropped. - Installs nvm for
USERvia the official install script, thennvm install <VERSION>andnvm alias <ALIAS> <VERSION>. - Installs
GLOBAL_PACKAGESwithnpm install -g, asUSER.
Configuration
| Variable | Default | What it does |
|---|---|---|
VERSION |
v22.20.0 |
the Node.js version nvm installs. A pin, not "latest LTS" — nvm's own version strings work, so --lts or 22 are accepted too. |
USER |
vagrant |
the user nvm is installed for. Everything lands in that user's ~/.nvm. |
ALIAS |
nodelts |
the nvm alias pointing at VERSION, so later cubes and scripts can say nvm use nodelts without knowing the number. |
GLOBAL_PACKAGES |
pm2 yarn local-web-server node-gyp inquirer execa @dotenvx/dotenvx |
space-separated, passed to one npm install -g. Setting it replaces the list rather than adding to it. |
SHELL |
fish |
the login shell to install through — fish or bash. See below. |
SHELL
nvm wires itself into whichever shell installed it, so this is not cosmetic.
fish(default) additionally requires Oh My Fish, because loading nvm goes through theomf install nvmplugin.user:addinstalls both, which is the usual way a host arrives here. The cube fails with one line, before changing anything, ifSHELL=fishon a host with no fish.bashneeds nothing beyond bash. Use it on a host whereuser:addhas not run.
The default stays fish so that an existing user — whose login shell user:add
set to fish — keeps getting a Node that their shell can actually see. Switching
would install it invisibly.
Dependencies
None declared: the cube runs standalone. With SHELL=fish it does have a real
prerequisite (fish + Oh My Fish, which user:add provides), but user:add is
deliberately not a declared dependency — it would create a user who is normally
meant to already exist. SHELL=bash is the standalone path.
Post-Installation
node is on USER's PATH in a login shell, not in root's and not in a
non-interactive one. To check:
su - <USER> -c 'node --version && npm --version'
From a bash script that is not a login shell, load nvm first:
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"
nvm use nodelts
PM2 — process manager
pm2 is in the default GLOBAL_PACKAGES, so it is installed unless you replaced
the list.
pm2 start app.js # Start application
pm2 list # List running apps
pm2 stop app # Stop application
pm2 restart app # Restart application
pm2 logs # View logs
pm2 startup # Enable PM2 on boot
pm2 save # Save current process list
pm2 startup prints a sudo command to run; it does not enable itself.
Notes
- Node.js is installed per user, under
~/.nvmforUSER. - Global packages belong to that user too, not to everyone on the host.
- Run the cube again with a different
VERSIONandALIASto have several versions side by side; nvm is built for exactly that.