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
- Process Management
- List Processes and Show Process Details
- Restart Processes After System Reboot
- Cluster Mode and Zero-Downtime Restarts
- Apply Actions to a Selected Process in Process File (JSON/JS/YAML)
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