Managing Node.js Applications with PM2

Node.js is an open-source runtime for JavaScript that allows execution of JavaScript code outside the browser. It is powered by Chrome’s V8 engine, known for speed and scalability, making it suitable for real-time and high-performance applications. Running Node applications in production comes with unique challenges — handling unexpected crashes, managing processes, and ensuring continuous uptime. PM2 is a Production Process Manager for Node.js applications that simplifies these tasks by providing monitoring, restart, and optimization features.

This guide explains how to manage Node.js applications using PM2, highlights its core features, and outlines best practices for production environments.

Prerequisites

Ensure you have access to your workstation as a non-root sudo user running macOS, Linux, or Windows with Node and NPM installed.

Install PM2 Using NPM

Install PM2 via the NPM package manager:

Create an Example Node.js Application

Follow these steps to create a sample Node.js application.

Navigate to the Home Directory

Create the Application File

Create a file named app.js with a text editor such as vim:

Add Code to the File

Insert the following code into the file:

const http = require('http');

const hostname = '0.0.0.0';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

The app.js file above is a simple Node.js web application that listens on port 3000. When it receives an HTTP request, it responds with the message “Hello World”.

Start the Application Using PM2

Start your Node.js application with PM2. Replace app.js with your application’s entry file if needed:

Your output should look similar to this:

[PM2] Starting /home/linuxuser/app.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ app                │ fork     │ 0    │ online    │ 0%       │ 4.4mb    │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

Additional Parameters

PM2 provides extra parameters to manage your application:

  • --name <app_name> – specify an application name
  • --watch – restart automatically when a file changes
  • --max-memory-restart <memory> – set a memory threshold for auto-restart
  • --log <log_file> – define a log file
  • --restart-delay <delay> – add a delay between automatic restarts (ms)
  • --time – add timestamps to logs
  • --no-autorestart – disable automatic restarts
  • --cron – use a cron job pattern for restarts
  • --no-daemon – prevent the app from running as a daemon

Visit the official documentation to see the full list of parameters.

Manage the Application

Use PM2 to manage your Node.js application with actions like restart, reload, stop, and delete.

Restart the Application

Reload the Application

Stop the Application

Delete the Application

List All Applications

List all applications currently managed by PM2:

Display Logs

View the logs generated by your application in real-time:

To view older logs, specify the number of lines with the --lines flag:

Monitor the Resource Usage

Monitor the resources consumed by your applications in near real time:

Set up a Web-Based Dashboard

Configure a web-based PM2 dashboard with the following command:

Follow the prompts to either create or log in to your PM2 account. If you don’t already have one, provide the required details and accept the license agreement.

You’ll see output similar to the following:

[PM2 I/O] Do you have a pm2.io account? (y/n) n
[PM2 I/O] No problem! We just need a few details to create your account.
[PM2 I/O] Please choose a username: vultrexampleuser
[PM2 I/O] Please choose an email: admin@example.com
[PM2 I/O] Please choose a password: ************
...
[PM2 I/O] Do you accept the terms and privacy policy (https://pm2.io/legals/terms_conditions.pdf)? (y/n) y
[PM2 I/O] Successfully authenticated
[PM2 I/O] Successfully validated
[+] PM2+ activated!
[PM2 I/O] Successfully connected to bucket PM2 Plus Monitoring
[PM2 I/O] You can use the web interface here: https://app.pm2.io/#/bucket/67cb27ccd623d57f6d4c63c0

Replace vultrexampleuser with your preferred username, admin@example.com with your login email, and provide a strong password to secure your account.

Next Steps

  • Open a web browser and go to the provided URL.
  • Log in with your PM2 credentials.
  • Start monitoring and managing applications through the PM2 Plus dashboard.

Note: PM2 Plus is a subscription-based service with costs depending on the number of processes you want to monitor. Check the PM2 Plus pricing page for details.

Configure PM2 to Start on Server Boot

Generate a startup script and configure PM2 to launch on server boot:

Your output should look like this:

[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/linuxuser/.nvm/versions/node/v22.14.0/bin /home/linuxuser/.nvm/versions/node/v22.14.0/lib/node_modules/pm2/bin/pm2 startup systemd -u linuxuser --hp /home/linuxuser

Copy the command from the output and execute it to make the PM2 process persistent:

$ sudo env PATH=$PATH:/home/linuxuser/.nvm/versions/node/v22.14.0/bin /home/linuxuser/.nvm/versions/node/v22.14.0/lib/node_modules/pm2/bin/pm2 startup systemd -u linuxuser --hp /home/linuxuser

The output will resemble this:

...
[PM2] Writing init configuration in /etc/systemd/system/pm2-linuxuser.service
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-linuxuser.service → /etc/systemd/system/pm2-linuxuser.service.
...

Configure Applications to Start on Server Boot

To ensure your PM2 applications start automatically on server boot, save them into a list:

Save Running Applications

Expected output:

[PM2] Saving current process list...
[PM2] Successfully saved in /home/linuxuser/.pm2/dump.pm2

Restore Applications Manually

If you need to restore saved applications manually from the list, use this command:

The output will look like this:

[PM2] Resurrecting
[PM2] Restoring processes located in /home/linuxuser/.pm2/dump.pm2
[PM2] Process /home/linuxuser/app.js restored
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ app                │ fork     │ 0    │ online    │ 0%       │ 21.3mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

Check for Updates

Print a list of outdated NPM packages on your system:

This command shows a list of globally installed NPM packages that have newer versions available.

Update PM2

Update the PM2 package via NPM. The update stops all running PM2 processes until the upgrade is completed, causing downtime for your applications:

$ npm install pm2@latest -g

Perform an in-memory update of PM2:

Best Practices and Security Considerations

Prevent Downtime With Cluster Mode

PM2 processes may restart multiple times during their lifecycle, which can cause temporary downtime. Use PM2’s cluster mode to minimize downtime. Cluster mode runs multiple instances of your application, ensuring that when one instance restarts, the others remain available to serve traffic.

First, delete the application before enabling cluster mode:

Start the application in cluster mode, specifying the number of instances with the -i parameter:

This command launches three instances of your application in cluster mode using PM2.

You can scale the application by specifying the new number of instances:

This command scales the application to four instances.

Eliminate Failed Requests With Graceful Shutdown

PM2 ensures graceful shutdowns by sending signals to your application, allowing it to exit cleanly. This prevents data loss or corruption by giving the app time to finish active tasks before shutting down.

PM2 manages graceful shutdowns as follows:

  • Before shutdown, PM2 sends a SIGINT signal to the application.
  • The application intercepts the signal.
  • It finishes active requests and closes resources such as database connections.
  • The application exits.

Add the following code to enable graceful shutdown in your application:

process.on('SIGINT', function() {
    // sigint signal received, log a message to the console
    console.log('Shutdown signal intercepted');
    // close the http server
    server.close();
    // exit the process
    process.exit();
});

The code above enables graceful shutdown. It intercepts the SIGINT signal, logs a message, closes the HTTP server, and exits the process cleanly.

Conclusion

In this article, you learned how to install and use PM2 to manage Node.js applications in production. You configured PM2 to start applications automatically on system boot, monitored resource usage, viewed logs in real time, and set up the web-based PM2 Plus dashboard. By following these steps, you can keep Node.js applications running reliably, recover from crashes automatically, and simplify operations with PM2’s extensive feature set. For more information, please visit the official documentation.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: