After testing different solutions, I’ve decided to create this “How To” tutorial listing solutions I’ve dealt with, considering Pro and Cons for each.

I hope you run your app on linux platform; if not, this guide could help you.

I will present solutions using a sample demo app as a reference — you can download app & docs from here.

[0]> Introducing Demo App

My reference app is built by 3 basic components:

1. app1 : runs every X msecs logging timestamp

2. app2 : runs every Y msecs logging timestamp

3. web : a simple express web app, which logs every request

Project Structure

Why an app like that? This is to simulate a basic complexity and avoid the super-simple node index.js use case (that is as easy as useless).

Moreover:

1. I want my app to be placed on different drive than C: — as a best practice, app shouldn’t be placed on the same drive of Windows OS. So, let’s use D.

2. app startup must accept an input parameter, which is “env” in my case. (I want, at least, discriminate production against dev, staging, uat, …)

3. optionally, I would prefer my app to run with a Windows Local user, not Administrative user. (spoiler: I still didn’t find a solution for that)

[1]> PM2

PM2 allows you to handle you application deployments. It provides several benefits, like for example logs management, automatic restart policies, application monitors, plus other things I’m missing.

Using PM2 with our app, we can:

1. start/stop/list components ( pm2 start apps/app1.js )

2. load a predefined configuration ( pm2 reload ecosystem.json.js )

3. save current configuration ( pm2 save )

4. restore previously saved configuration ( pm2 resurrect )

[1a]> PM2_HOME

When you install PM2 ( npm install -g pm2 ), it creates a default PM2 home folder (under C:\Users\<username>\.pm2 ) that will store PM2 relevant files, like logs (yes, the same you see running pm2 logs ), process pid or the dump that is created when you run pm2 save . I recommend to run your PM2 commands and check how files change in that folder.

Now, we will move that folder to a brand new folder: c:\etc\.pm2

Follow these steps:

1. Create a new folder c:\etc\.pm2

2. Create a new PM2_HOME variable (at System level, not User level) and set the value c:\etc\.pm2

3. Close all your open terminal windows (or restart Windows)

4. Ensure that your PM2_HOME has been set properly, running echo %PM2_HOME%

Set PM2_HOME

This is crucial for every further step.

The key point for PM2 on Windows is to set up Windows an environment variable PM2_HOME at system level. If you miss that, you’ll get troubles.

[1b]> PM2 save

Another important aspect is to understand how pm2 save that is the base of all the solutions described below.

(1) Create a file ( ecosystem.config.js )that describes how the application should starts.

(2) Load configuration running:

pm2 reload ecosystem.config.js --env=production

(3) Check that your application is working as expected

(4) If everything is ok, save your configuration: pm2 save

Load and Save your app configuration

Now, the final step is to test that everything has been done properly.

(1) Kill PM2 running: pm2 kill

(2) Restart PM2: pm2 resurrect

Test that everything is ok

These 2 commands are exactly what we need to run on Windows startup :)

[2]> Solutions

Now we are ready to go though different solutions:

2a. Using NSSM

2b. Using pm2-windows-service

Both implements shares the same idea: create a Windows Service that, when Windows starts, will take care of starts PM2 ( pm2 resurrect ) and load a specific PM2 configuration (the one that we saved with pm2 save ).

[2a]> Solution1: Using NSSM

Solution1: introduction

We will create a service called MyPM2Service using NSSM, which is a great tool to create/edit/remove Windows Services (much better than Windows default one…).

So:

0. Before start, did you already setup PM2_HOME and run pm2 save ? No?!? It’s definitely time to do that.

1. Create your PM2 startup script which implements pm2 resurrect .

Check out sample here (pm2_startup.bat)

2. As administrator, open command line, run:

nssm.exe install MyPM2Service

and set the following:

Path: D:

ode-pm2-windows-guide\...\pm2_startup.bat

Folder: D:

ode-pm2-windows-guide\

Startup Type: Automatic delayed

Restart: None

This will create a Windows Service called MyPM2Service (If you want to delete service, run: nssm.exe remove MyPM2Service )

3. That’s it.

Install Service with NSSM

Solution1: testing

To test:

1. Restart Windows

2. Just after restart, open command prompt (as Administrator) and run

pm2 status → our application is running ;)

Solution1: considerations, pro&cons

[◼️] it works ;)

[◼️] you can check Service startup on Windows Event Viewer

[◻️] application startup now require Administrator privileges

[◻️] if you stop MyPM2Service, pm2 will not stop

[◻️] not a big issue, but there are no logs for Windows Service itself, that sometimes could be useful to debug if something went wrong…

[2b]> Solution2: Using pm2-windows-service

Solution2: introduction

We will create a Windows Service using Node module pm2-windows-service, check here for more info.

So:

0. Before start, did you already setup PM2_HOME and run pm2 save ? No?!? It’s definitely time to do that.

1. Install Node module

npm install -g pm2-windows-service

2. As administrator, open command line, run:

pm2-service-install -n PM2

and set the following:

? Perform environment setup (recommended)? Yes

? Set PM2_HOME? Yes

? PM2_HOME value (this path should be accessible to the service user and

should not contain any “user-context” variables [e.g. %APPDATA%]): c:\etc\.pm2\

? Set PM2_SERVICE_SCRIPTS (the list of start-up scripts for pm2)? No

? Set PM2_SERVICE_PM2_DIR (the location of the global pm2 to use with the service)? [recommended] Yes

? Specify the directory containing the pm2 version to be used by the

service C:\USERS\<USER>\APPDATA\ROAMING\NPM

ode_modules\pm2\index.js

PM2 service installed and started.

This will create a Windows Service called PM2

3. That’s it.

Install Service with pm2-windows-service

Solution2: testing

To test:

1. Restart Windows

2. Just after restart, open command prompt (as Administrator) and run

pm2 status → our application is running ;)

Run as Administrator!

Solution2: considerations, pro&cons

[◼️] it works ;)

[◼️] you can check Service startup on Windows Event Viewer

[◼️] you can use Windows Service to start/stop the application

[◻️] startup now require Administrator privileges