Ubuntu's APT repos ship a Node.js that lags by a year or more. For production deployments, install Node.js 20 LTS straight from NodeSource — it is the same package the Node project signs and is what most CI providers use.
Prerequisites
- Ubuntu 22.04 or 24.04 with
sudo. - Outbound TCP/443 to
deb.nodesource.com. - An idea of which Node major you actually need — 20 LTS for current, 18 LTS only if forced.
Step 1: Remove any older Node from the distro repo
sudo apt remove -y nodejs npm libnode-dev 2>/dev/null || true
sudo apt autoremove -y
Step 2: Add the NodeSource repository
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \
| sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt update
Step 3: Install Node.js 20
sudo apt install -y nodejs
node --version # v20.x
npm --version
npm ships inside the nodejs package — no separate install.
Step 4: Set up a non-root global directory
npm install -g defaults to /usr/lib/node_modules, which forces sudo for every global package. Re-point it at your home so you can npm i -g without root.
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g pnpm yarn pm2
Step 5: Use pm2 to keep apps alive
For one-off Node services, pm2 is the lightest path to "process running after I log out."
cd /var/www/myapp
pm2 start npm --name myapp -- start
pm2 save
pm2 startup systemd # follow the printed sudo line
Verify
node -e 'console.log("Node " + process.version + " is alive")'
npm doctor
pm2 ls
Conclusion
NodeSource gives you the same Node binaries as the upstream project, with apt's familiar update flow. Add pm2 (or a systemd unit) on top and you have a production-shaped Node host.
Next steps
- Front the app with Nginx as a reverse proxy (same recipe works on Ubuntu).
- Lock down inbound traffic via UFW for specific ports.
- For container-first deployments see Docker + Compose on Ubuntu.
Comments
0 total · 0 threads