Keep a Node.js app online with PM2
A Node.js application started with node index.js stops when the SSH session closes or an uncaught exception occurs. PM2 is a process manager that keeps it alive, restarts it and brings it back after a reboot. It does not replace fixing a bug or monitoring, but it prevents avoidable outages.
Install Node.js and PM2
sudo apt update
sudo apt install -y nodejs npm
node --version
sudo npm install -g pm2
pm2 --versionDebian 13 ships Node.js 20. If your application requires Node.js 22 or 24, add the NodeSource repository and pin the version you need. PM2 is installed globally, but the application must run under a non-privileged user, for example deploy.
Start the application
The application must read its port from the environment and listen on all interfaces:
const port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", () => {
console.log(`Listening on ${port}`);
});Then, as deploy:
cd /var/www/app
npm ci --omit=dev
pm2 start index.js --name app
pm2 status
curl -I http://127.0.0.1:3000/An ecosystem.config.cjs file makes startup reproducible: instances, max_memory_restart, env and time for log timestamps. Do not run PM2 as root: the application does not need those privileges, and a vulnerability would immediately become system-wide.
Start at boot
pm2 startup systemd -u deploy --hp /home/deploy
pm2 save
systemctl status pm2-deploypm2 startup prints a sudo command; run it exactly as shown. pm2 save records the process list: without it, nothing restarts after a reboot. Actually test with sudo reboot, then check pm2 status after reconnecting.
Operations and limits
pm2 logs app --lines 100
pm2 reload app
pm2 monitreload restarts without dropping connections in cluster mode; restart does drop them. Install log rotation, otherwise logs fill the disk:
pm2 install pm2-logrotatePM2 does not replace monitoring, backups or a reverse proxy. A memory leak triggers max_memory_restart in a loop: fix the cause instead of raising the limit. In cluster mode, the application must be stateless, with sessions in Redis or the database. Finally, check that Nginx points to the local port and that the application port is not public.
On Pterodactyl application hosting, startup and restarts are handled by the panel: PM2 is for VPS instances where you administer the system.
Advertisement
Was this article helpful?
Read next
- Deploy a stack with Docker ComposeDeploy an application and its database with compose.yaml, persistent volumes and variables outside Git.
- Enable HTTPS with CertbotObtain and renew a Let's Encrypt certificate with Certbot and Nginx, then enable HSTS carefully.
- Install Docker on DebianInstall Docker from the official repository, verify the daemon and understand the limits of a system container.