PM2 — Restart Processes After System Reboot

Previously, we published a guide on how to manage processes with PM2. The guide didn’t describe how to restart the PM2 process and managed applications after a system reboot. This is an essential feature for a process manager, because you heavily rely on system and server startup automation. You don’t want to worry all the time that your server might fail and you have to SSH into the machine to start the applications.

This article is part of a comprehensive PM2 series and the following list depicts related posts.

PM2 Series Overview

Introduction

We use a ubuntu/trusty64 Vagrant box to test the code shown within this post. We could have used our actual machine (Mac) to test if processes are restored after boot, but (to be honest) we didn’t want to restart the system multiple times to check whether everything works fine. It’s much easier to just bootstrap the vagrant box, install Node.js including NPM, install PM2 and test the functionality.

You can use the following Vagrantfile if you want to give it a try:

Vagrant.configure(2) do |config|  
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.provision "shell", inline: <<-SHELL
    sudo apt-get update
    sudo add-apt-repository ppa:nginx/stable
    sudo apt-get install -y software-properties-common
    sudo apt-get update
    sudo apt-get install -y nginx

    curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
    sudo apt-get install -y nodejs
  SHELL
end  

Once your box is booted, create a simple Node.js server and update the nginx config to proxy requests to your app.

Startup Script Generation

PM2 ships with the functionality to generate startup scripts for multiple init systems. These scripts are executed on system boot and with that spawn the PM2 process itself which is required to (re)start application servers.

You can generate a startup script for your server’s init system by either using PM2’s auto-detection feature or pass a specific init system name to the startup command. If you don’t know your init system, just run pm2 startup without arguments to let PM2 auto-detect.

pm2 startup  
# or
pm2 startup <init-system>  
# <init-system> is one of these options
# systemd|upstart|launchd|rcd|systemv

The startup command will generate another command which you need to execute as root on your system.

Since we use an Ubuntu (14.04) box to test the restart on boot feature, we precisely pass upstart as the init system’s name to make sure we don’t get caught in a nasty bug caused by not defining the init-system.

$ pm2 startup upstart
[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup upstart -u vagrant --hp /home/vagrant  

Execute the generated command to daemonize PM2 and generate the system’s init script which is executed on boot.

$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup upstart -u vagrant --hp /home/vagrant
Platform upstart  
Template  
#!/bin/bash
…
[PM2] Writing init configuration in /etc/init.d/pm2
[PM2] Making script booting at startup...
…
[DONE]
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save

[PM2] Remove init script via:
$ pm2 unstartup upstart

PM2 is configured to be started on boot, but we didn’t have any application to restart. Let’s start a Node.js server with PM2.

Start Node.js Server

You can use any of your personal applications or just create a new one for testing purposes.

We use the exemplary code from Node’s startpage and kick off the server with PM2.

$ pm2 start server.js
[PM2] Starting server.js in fork_mode (1 instance)
[PM2] Done.
---------------------------------------------------------------------------------------------------
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ memory     │ watching │
---------------------------------------------------------------------------------------------------
│ server   │ 0  │ fork │ 2065 │ online │ 0       │ 0s     │ 22% │ 6.664 MB   │ disabled │
---------------------------------------------------------------------------------------------------

Save Processes for Restart on Boot

There is one more thing to do: save the process list which should be restarted on system boot.

$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/vagrant/.pm2/dump.pm2

This dumps the process list to disk which can be restored easily. The process list gets populated into ~/.pm2/dump.pm2 and is accessable for PM2 for process resurrection.

That’s all the magic. Go ahead and see if the processes restart after system reboot.

What if Processes Don’t Start on Boot?

We had issues getting PM2 itself and the managed processes to be restored on system boot and the reason was wrong permissions. PM2 itself should be started with system boot which requires root privileges to be kicked off with other system services. However, the application processes run within the scope of another system user, let’s call him nodeuser.

We solved the boot issue by passing the -u nodeuser parameter to PM2’s startup command. That concretely defined nodeuser as the user for which we want to resurrect the saved processes.

$ pm2 startup -u nodeuser

PM2 will generate a new startup script and you need to execute the snippet with root privileges again.

Manually Restore Processes

If you’ve saved your process list earlier, but PM2 didn’t restore them on boot, you can manually resurrect them:

$ pm2 resurrect

This will bring the dumped processes back online and you don’t need to manually start every single server. This command expects that you’ve saved your processes so there is something to restore.

What Comes Next

We hope this guide helps you to configure your production environment to be robust against system reboots and you don’t have to worry about spontaneous system restarts.

Within the next post, we’ll show you how to use PM2’s integrated monitoring utility to get a sense of your app’s CPU and memory utilization.

Did you discover something important that we missed within this post? Please let us know in the comments or give us a tweet @futurestud_io


Additional Resources

Explore the Library

Find interesting tutorials and solutions for your problems.