LazyCodet

a

22:24:33 17/12/2024 - 1 views -
Programming

Mastering PM2: Understanding pm2 save and pm2 startup

In the world of Node.js applications, ensuring that your applications are robust and resilient to unexpected downtime is crucial. PM2 (Process Manager 2) is a powerful tool used to manage production workloads with ease. One of the essential features it offers is the ability to keep processes running across server reboots seamlessly. This is primarily achieved through the use of two fundamental commands: pm2 save and pm2 startup. In this blog post, we’ll dive deep into how these commands work and why they are critical for maintaining application uptime.

What is PM2?

Before we delve into specifics, let's quickly revisit what PM2 is. PM2 is a popular process manager for Node.js applications. It allows you to define, manage, and monitor your applications easily. With features like clustering, log management, monitoring, and load balancing, PM2 helps ensure that your applications run smoothly in a production environment.

Understanding pm2 save

The command:

pm2 save

Purpose

The primary purpose of the pm2 save command is to create a snapshot of your current running PM2 processes. This snapshot is written to a file located in the PM2 directory (~/.pm2/dump.pm2). Think of it as a backup of your current process list, which includes all the details necessary to restart these processes later.

Use Case

  • Why Save? If your system undergoes a reboot or crashes, you'll want your Node.js applications to restart automatically. However, without saving your process list, PM2 won't know which applications were running before the reboot.
  • When to Save? You should execute pm2 save after starting or stopping any application changes you wish to persist across reboots. It’s a good practice to make this a habit whenever you modify your process list.

Executing pm2 startup

The command:

pm2 startup

Purpose

The pm2 startup command generates and configures a startup script specific to your system's init system (e.g., systemd, upstart, launchd). This script ensures that the PM2 daemon starts on boot, enabling any saved processes to be resurrected automatically.

Use Case

  • System Boot Management To automatically manage your Node.js processes upon system boot, the PM2 daemon itself needs to start. pm2 startup takes care of configuring your system to launch PM2 automatically during boot.
  • Why Combine with pm2 save? While pm2 startup ensures the PM2 daemon runs on boot, it’s pm2 save that ensures your specific processes are restored. Without both, your applications may not return to their previous state after a reboot.

Step-by-Step: Ensuring Resilience with PM2

Here's a simple step-by-step guide to making sure your Node.js applications are managed across reboots:

  1. Start Your Applications Launch your Node.js applications using PM2:
    pm2 start app.js
  2. Save the Process List Capture the current processes:
    pm2 save
  3. Setup Startup Script Generate and configure the startup script:

    After executing this command, follow any additional instructions provided by PM2 to run the generated command with root privileges.

    pm2 startup
  4. Verify Configuration Reboot your system and verify that PM2 and your applications have restarted:
    pm2 ls

Bonus: An error I got that was so crazy - PM2 cached the version of Node

​One time, I had a Nuxt app running on my VPS. After that, I upgraded the VPS, and of course, it needed to reboot. This time, my app does not start up successfully with pm2 because my VPS uses the old version of Node is 12, but my application works well with Node 20. So I switched to Node 20, but PM2 still keeps the old version is 12, so when I run pm2 start, I got an error like this:

0|LazyCode | Listening on http://[::]:3000
/root/.pm2/logs/LazyCodet-Nuxt-out-2.log last 15 lines:
/root/.pm2/logs/LazyCodet-Nuxt-out-3.log last 15 lines:
/root/.pm2/logs/LazyCodet-Nuxt-error-0.log last 15 lines:
0|LazyCode |     at WriteStream.<anonymous> (/usr/local/lib/node_modules/pm2/lib/Utility.js:186:13)
0|LazyCode |     at WriteStream.emit (events.js:314:20)
0|LazyCode |     at internal/fs/streams.js:366:10
0|LazyCode |     at FSReqCallback.oncomplete (fs.js:156:23)
0|LazyCode | Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/www/nuxt-app/releases/release-215/server/index.mjs
0|LazyCode |     at Module.load (internal/modules/cjs/loader.js:861:11)
0|LazyCode |     at Function.Module._load (internal/modules/cjs/loader.js:708:14)
0|LazyCode |     at /usr/local/lib/node_modules/pm2/lib/ProcessContainer.js:304:25
0|LazyCode |     at wrapper (/usr/local/lib/node_modules/pm2/node_modules/async/internal/once.js:12:16)
0|LazyCode |     at next (/usr/local/lib/node_modules/pm2/node_modules/async/waterfall.js:96:20)
0|LazyCode |     at /usr/local/lib/node_modules/pm2/node_modules/async/internal/onlyOnce.js:12:16
0|LazyCode |     at WriteStream.<anonymous> (/usr/local/lib/node_modules/pm2/lib/Utility.js:186:13)
0|LazyCode |     at WriteStream.emit (events.js:314:20)
0|LazyCode |     at internal/fs/streams.js:366:10
0|LazyCode |     at FSReqCallback.oncomplete (fs.js:156:23)
...

I'm so crazy about this error. When I got this error, I searched the issue with the key  "Error [ERRREQUIREESM]: Must use import to load ES Module" but you know, this is the wrong direction.

​So I spent 6 hours on this, and I realized the issue. I found a solution [1] to update PM2 using the current node version:

pm2 update

​And I found a useful command to check the information of PM2, and of course, it consist of the version is used by PM2

pm2 monit

​This is the UI of it:

Pasted Image

Conclusion

Understanding and utilizing pm2 save and pm2 startup is vital for any developer or system administrator aiming to maintain high availability for Node.js applications. By saving your process list and ensuring that PM2 itself starts on boot, you gain peace of mind knowing your applications will automatically resume after a system reboot. Implement these practices to enhance your application's resilience and reliability with PM2.

References

​[1] - https://stackoverflow.com/a/63057283/21614343