Keep a Node.js app online with PM2

2 min read07 November 2026

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

Bash
sudo apt update
sudo apt install -y nodejs npm
node --version
sudo npm install -g pm2
pm2 --version

Debian 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:

JavaScript
const port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", () => {
  console.log(`Listening on ${port}`);
});

Then, as deploy:

Bash
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

Bash
pm2 startup systemd -u deploy --hp /home/deploy
pm2 save
systemctl status pm2-deploy

pm2 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

Bash
pm2 logs app --lines 100
pm2 reload app
pm2 monit

reload restarts without dropping connections in cluster mode; restart does drop them. Install log rotation, otherwise logs fill the disk:

Bash
pm2 install pm2-logrotate

PM2 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