Install Node.js with nvm and Run an App with pm2

23 Apr 2026 By Edgars Kalējs

Run on the server with one command (check the script contents below first):

curl -sSL https://cp.lv/scripts/ustanovit-nodejs-pm2.sh | sudo bash

…or with wget:

wget -qO- https://cp.lv/scripts/ustanovit-nodejs-pm2.sh | sudo bash

Script contents ustanovit-nodejs-pm2.sh:

#!/usr/bin/env bash
set -e

APP_DIR=/var/www/myapp

# 1. Install nvm and load it into the current shell
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

# 2. Node.js LTS as the default version
nvm install --lts
nvm use --lts
nvm alias default 'lts/*'

# 3. Application dependencies (exact versions from the lock file)
cd "$APP_DIR"
npm ci --omit=dev

# 4. Install pm2 and start the application
npm install -g pm2
pm2 start app.js --name myapp

# 5. Start automatically after a server reboot
sudo env PATH=$PATH:$(dirname "$(command -v node)") \
  pm2 startup systemd -u "$USER" --hp "$HOME"
pm2 save

pm2 status
echo "Node.js application myapp is running under pm2."

For a Node.js application to run reliably in production, you cannot simply start it with node app.js in an SSH session — it stops when you log out. You need the pm2 process manager: it keeps the application alive, restarts it after a crash and brings it back after a server reboot. Node.js itself is best installed through nvm, which makes switching versions easy.

Step 1. Install nvm

nvm (Node Version Manager) installs Node.js without root rights and lets you keep several versions side by side:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc

Check it:

nvm --version

Step 2. Install Node.js LTS

Install the LTS release — it is stable and gets long-term support:

nvm install --lts
nvm use --lts
nvm alias default lts/*

Check the versions:

node -v
npm -v

Step 3. Prepare the application

Upload the code (with git clone or rsync) and install the dependencies in production mode:

cd /var/www/myapp
npm ci --omit=dev

npm ci installs the exact versions from package-lock.json — more predictable than npm install. Check that the application starts:

node app.js

If you see “server listening on port 3000”, stop it (Ctrl+C) and move on to pm2.

Step 4. Install pm2 and start the app

Install pm2 globally and start the application:

npm install -g pm2
pm2 start app.js --name myapp

For applications whose entry point is declared in package.json:

pm2 start npm --name myapp -- run start

Check the status:

pm2 status
pm2 logs myapp

Step 5. Autostart after a reboot

So that pm2 brings the applications up when the server starts, generate a systemd service and save the process list:

pm2 startup systemd
# run the command pm2 prints (it starts with sudo env ...)
pm2 save

pm2 save records the current set of processes, and pm2 resurrect restores them automatically after a reboot.

Step 6. Cluster mode (optional)

If the application supports several workers, pm2 can run a process on every CPU core:

pm2 start app.js --name myapp -i max

That balances the load across the cores without an external balancer.

Useful pm2 commands

Task Command
List processes pm2 list
Restart pm2 restart myapp
Graceful reload pm2 reload myapp
Stop pm2 stop myapp
Remove from pm2 pm2 delete myapp
Monitoring pm2 monit

FAQ

Why use nvm if Node.js is in apt? The version in the Ubuntu repository is often outdated. nvm installs any version you need and lets you switch quickly between projects with different requirements.

What is the difference between pm2 restart and reload? restart restarts the process completely (with a short outage), while reload in cluster mode restarts the workers one by one with zero downtime.

My app crashes — will pm2 bring it back? Yes, pm2 restarts a crashed process automatically. Set --max-restarts and watch the logs so a permanent error does not turn into a restart loop.

How do I limit the memory a process uses? The --max-memory-restart 300M flag restarts the application when it exceeds the limit — protection against memory leaks.

Node.js applications benefit from a fast CPU and enough memory. You can pick a server on the VPS hosting page, and for containerised builds there is Docker VPS.

Edgars Kalējs