Install Node.js on an Ubuntu VPS, Step by Step

You just ordered a fresh Ubuntu 24.04 VPS, you SSH'd in, and now you need Node.js running for your API or bot. The fastest path is a distro package, but for real work you want the current LTS managed by NVM, so you can switch versions and avoid sudo permission fights later. This guide walks through the exact steps to install Node.js on an Ubuntu VPS, lock it down, and keep the process alive in production with PM2.
Prerequisites
- An Ubuntu 24.04 LTS VPS, with a non-root sudo user. If you are starting from the root account, create a sudo user first.
- A Linux VPS with at least 1 GB RAM. Node itself is light, but your app and build tools will want headroom.
- SSH access configured. If this is your first time, review how to connect to a linux vps over ssh for the first time before continuing.
- A domain name if you plan to expose the app over HTTPS later, though it is not required for the install itself.
Why not just use the Ubuntu package for Node.js?
The Ubuntu repositories carry a Node.js version, and apt install nodejs works. But the version lags behind the official releases, and the node binary installs to /usr/bin, which means global packages require root. On a VPS that you control, this gets annoying fast: every npm i -g becomes a sudo dance, and permissions get tangled the moment you run a build script as a normal user.
NVM installs Node into your home directory, so your user owns everything. That is the standard way to install Node.js on an Ubuntu VPS for development and for production apps that you manage yourself. It also lets you keep multiple versions side by side, which matters when you run several projects with different engine requirements.
Step 1 - Installing NVM on Ubuntu 24.04
NVM is a shell script, not a system package. The project keeps the install script at a stable URL. Run it with curl, then source the new environment:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
The install script appends a few lines to your .bashrc or .zshrc. The export lines above load NVM into the current shell; if you open a new terminal you will not need to run them again. Verify that NVM is present before moving on:
nvm --version
Expected output is a version number like 0.40.3. If the command is not found, close the SSH session and reconnect so the shell reads the updated profile.
Step 2 - Installing the current Node.js LTS
As of 2026, Node.js 24 is the Active LTS line, supported until April 2028, and Node.js 22 is in Maintenance LTS. For a new project, install the current LTS. NVM knows the alias by name:
nvm install --lts
nvm use --lts
node -v
npm -v
nvm install --lts resolves to the newest LTS release, which is currently Node.js 24. The node -v command should print something like v24.x.x, and npm -v prints the bundled npm version. If you later need a specific major version, nvm install 22 works the same way.
Set this version as the default so every new shell uses it:
nvm alias default 'lts/*'
This matters on a VPS. If you reboot the machine, or if you run commands through a non-interactive shell like a systemd unit, the default alias decides which Node runs.
Step 3 - Configuring npm for a production VPS
Out of the box, npm writes global packages into the NVM directory, which is correct. But two settings are worth changing on a production VPS or any server hosting an application: the registry and the cache. The default registry is fine in most regions, but keep the cache local to the machine:
npm config set cache "$HOME/.npm"
npm config set audit true
npm config ls
The audit setting is on by default, but listing the config confirms the cache path points at your home directory, which is what you want on a single-user VPS. There is no need to run npm as root, and with the NVM install you never have to.
Step 4 - Installing PM2 and running your first app
Plain node app.js dies when you close the SSH session. PM2 is the process manager that keeps Node apps alive on a VPS, restarts them after a crash, and stores logs in a predictable place. Install it globally with npm:
npm install -g pm2
pm2 --version
To test, create a minimal server and start it under PM2:
mkdir -p ~/hello && cd ~/hello
cat > server.js <<'EOF'
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello from Node.js on Ubuntu\n');
}).listen(3000);
EOF
pm2 start server.js --name hello
pm2 save
pm2 save records the process list so that pm2 resurrect can restore it. On a VPS you want that snapshot, because PM2 does not start apps automatically just because it is installed. You will set up the startup script next.
Step 5 - Keeping PM2 alive across reboots
A VPS reboot clears the process table. PM2 has a startup utility that generates a systemd unit for exactly this case:
pm2 startup systemd -u $(whoami) --hp "$HOME"
The command prints a sudo env ... line. Run the command it shows, then verify the service is enabled:
systemctl status pm2-$(whoami) --no-pager
Expected output includes active (running) and a line saying the unit file is enabled. From here, PM2 restarts your Node processes automatically whenever the Ubuntu VPS boots, which is the behavior you want for a production API or a bot that must stay online.
Step 6 - Opening the firewall and verifying the service
Ubuntu ships with ufw, and it is usually inactive on a fresh VPS. If you enabled it earlier, allow the port your app listens on. For the test app above, that is port 3000:
sudo ufw allow 3000/tcp
sudo ufw status
If ufw is inactive, the status command reports that. In that case, decide whether to enable it now. For a public-facing app, enabling the firewall is the right call, but do it carefully so you do not lock yourself out of SSH:
sudo ufw allow OpenSSH
sudo ufw allow 3000/tcp
sudo ufw enable
Verify the app responds locally and through the public interface:
curl -I http://127.0.0.1:3000
curl -I http://$(hostname -I | awk '{print $1}'):3000
Both should return HTTP/1.1 200 OK. The first confirms the process runs; the second confirms it binds to the VPS network interface, not just loopback. If the second fails, check that the app listens on 0.0.0.0 or the specific public IP rather than only 127.0.0.1.
Step 7 - Setting up the project directory the right way
Server apps should not run from a random path in your home folder. Create a standard layout early, because restructuring later means updating PM2 paths and possibly breaking running processes:
sudo mkdir -p /var/www/myapp
sudo chown -R $USER:$USER /var/www/myapp
cd /var/www/myapp
git clone <your-repo-url> .
npm install --production
Keeping apps under /var/www matches the convention used by nginx and other web servers. The ownership change lets your normal user write there without sudo. If you are running several services, this layout also makes backup scripts and log rotation simpler, because everything lives in one place.
Step 8 - Monitoring logs and troubleshooting common failures
PM2 centralizes logs, which saves you from hunting through journalctl for application output. The most useful commands when something breaks:
pm2 logs hello --lines 50
pm2 status
journalctl -u pm2-$(whoami) --no-pager -n 30
Three failures show up constantly when people install Node.js on an Ubuntu VPS for the first time.
Port already in use. The app starts and dies immediately. Check with ss -tlnp | grep 3000; if another process holds the port, either stop it or change your app port. Do not guess, the ss output names the offending process.
Express or another package not found. You ran node app.js but npm install ran as a different user, or you installed dependencies with --production and the app needs a dev dependency at runtime. Rebuild with npm install in the project directory and restart PM2.
NVM command not found in non-interactive shells. A systemd unit or a cron job runs with a minimal environment that does not source .bashrc. The fix is to use the absolute path to the node binary. Find it with which node after nvm use, then put that full path in your unit file or cron command. PM2 units usually work because PM2 stores the resolved path when you first start the app.
Node.js version management on a day-to-day basis
Once the LTS installs, resist the urge to chase every odd-numbered release. Odd versions like 25 or 27 ship as "Current" and only enter LTS after a year, which means they receive non-backported changes. For a production VPS, staying on the LTS line is the disciplined choice. Use nvm ls to list installed versions and nvm install lts/* to jump to the next LTS when one is released.
When a security update lands for Node.js, the update process is two commands:
nvm install --lts --reinstall-packages-from=current
pm2 restart all
The first command installs the patched LTS and carries your global packages over. PM2 restarts the processes so they run on the new binary. That is the whole maintenance story, and it is why NVM beats a system package for anyone who manages their own VPS applications.
FAQ
Do I need root to install Node.js on an Ubuntu VPS?
No. The NVM method installs Node entirely inside your home directory. You only need sudo for the PM2 startup unit and firewall rules, which are system-level changes.
Which Node.js version should I install on Ubuntu 24.04 in 2026?
Install the current LTS, which is Node.js 24, supported until April 2028. NVM resolves it with nvm install --lts.
How do I start a Node.js app automatically after a reboot?
Run pm2 startup systemd, execute the printed sudo command, then pm2 save. The generated systemd unit restarts all saved PM2 processes on boot.
Why does my Node.js app stop when I close SSH?
Because the process belongs to your SSH session and receives a SIGHUP when the session ends. Running it under PM2 detaches it from the session so it survives.
Can I run multiple Node.js versions on one VPS?
Yes, NVM keeps them side by side. Use nvm install 22 to add an older LTS and nvm use 22 to switch per shell or per project.
Related articles
- Run Node.js in production on a VPS with PM2
- Install Docker on an Ubuntu VPS
- Set up a LEMP stack on Ubuntu 24.04
- Connect to a Linux VPS over SSH for the first time
Ubuntu VPS 安装 Node.js 完整指南
2026 年安装 Node.js 的首选方式是使用 NVM 管理当前 LTS 版本,即 Node.js 24。安装后必须配置 PM2 进程管理器并生成 systemd 启动单元,这样 VPS 重启后应用才能自动运行。生产环境建议将应用放在 /var/www 目录,并使用 pm2 logs 排查故障。升级安全补丁时执行 nvm install --lts 后重启 PM2 即可,无需重新配置。


