How to keep a Node.js app running

Run a long-lived Node.js process reliably on TurboStack.

A Node.js application is a long-lived process. If it crashes, or the server reboots, it must start again on its own - otherwise Nginx has nothing to forward to and returns a 502 error. On TurboStack you keep it running with the pm2 process manager (a systemd service is the alternative).

pm2 keeps the app running with auto-restarts, manages several apps at once, and gives you monitoring and log viewing in one place.

Before you start

  • SSH access to the host - see SSH access. Run these commands as your system user.

  • The Node.js runtime enabled on the application, and your app listening on the local port set as proxy_upstream_port so Nginx can proxy to it - see Configure Node.js and the reverse proxy. When you enable the Node.js runtime, pm2 is installed for you by the node package manager, so there is nothing extra to install.

Deploy and start your app under pm2

If you migrated from another environment, reinstall dependencies cleanly first so no incompatible or corrupted modules are left behind:

cd ~/app
rm -rf node_modules      # only when migrating or dependencies changed
npm install              # rebuild node_modules
npm run build            # build the app (for example a Next.js build)

Then start it under pm2 and give it a name:

pm2 start npm --name app -- start     # runs "npm start"
# or run a file directly:
pm2 start server.js --name app

Check that it is running:

pm2 ls

Make it survive reboots

TurboStack already provisions a platform-managed pm2-<user> system service that starts pm2 and your saved processes at boot, so you do not run pm2 startup yourself (as a non-root user it only prints a sudo line and cannot complete). What you must do is save the current process list so the platform service brings the right apps back:

pm2 save       # save the current process list - run this again after every change

Monitor and read logs

pm2 ls                 # list processes with status, CPU, memory and restart count
pm2 show app           # details for one process
pm2 logs app           # live logs (use --lines 200, --err or --out to narrow)
pm2 monit              # live dashboard: CPU/memory per app, status, restarts, real-time logs

Restart after a change or deploy

pm2 restart app        # full restart
pm2 reload app         # zero-downtime reload (for cluster-mode apps)

When you change dependencies or move the app from another environment, reinstall cleanly first to avoid incompatible modules:

rm -rf node_modules
npm install
pm2 restart app

Check which process manager is configured

To see which manager each application user runs under, use the TurboStack CLI:

tscli app backends

Alternative: a systemd user service

Instead of pm2 you can run any long-lived app (Node.js, Python, a custom worker) as a systemd user service. It needs no root, integrates with journalctl for logs, and restarts on crash and on boot. Use pm2 when you want its process dashboard and zero-downtime reloads; use a systemd service when you prefer one consistent way to run every background process on the host.

For the unit file and the systemctl --user commands, see How to manage user system services.