I use PM2 as the process manager for my NodeJS apps in production and staging servers among others.
PM2 now has a deployment pipeline built-in but the documentation is a bit underdone in my opinion. So after, digging around in the code and documentation, I pieced together this guide to get you started on using PM2 not just to manage your NodeJS apps, but deploy them to servers as well.
TL;DR I use PM2 to deploy for mid to small sized apps which have a fixed number of servers running the applications. For applications where I need to spin up servers automatically using the same configurations when needed, I rely on Ansible to spin up new servers and deploy to them.
To get started, install pm2
as a global package on your local machine -
npm install -g pm2
Once that is done, navigate to your project folder and create the deployment file using pm2 ecosystem
. This generates an ecosystem.json
file in your project folder which contains sample configurations for managing PM2 applications and deployment pipeline. Here, you can opt to just generate a file under a different name, e.g deploy.json
. You necessarily don’t have to use ecosystem.json
as the file.
Open the newly created/generated .json
file in your editor. This is what a typical description file will look like:
{
"apps" : [
{
"name": "myApp",
"script": "server.js",
"instances": 2,
"exec_mode": "cluster_mode",
"env_production": {
"NODE_ENV": "production",
"MONGO_URI": "mongodb://myuser:mypassword@192.168.0.000:27017/myApp?authSource=admin",
"COOKIE_SECRET": "mySecret"
}
}
],
"deploy": {
"production": {
"key": "myApp.pem",
"user": "node",
"host": ["<ip-server>", "<ip-server>"],
"ref": "origin/master",
"repo": "git@github.com:myApp/myApp.git",
"path": "/var/www/myApp",
"post-deploy" : "mkdir -p logs && touch logs/all-logs.log && npm install --production && pm2 startOrRestart ecosystem.json --env production",
"pre-deploy-local" : "echo 'Deploying code to servers'"
}
}
}
In lines 2-14
, the apps
array contains the definition for your application that PM2 needs to manage.
Lines 6-7
is required if you want your application to make use of multi-core servers. PM2 uses Node’s internal cluster module to make this possible under the hood.
Lines 8-11
contain the environment variables that your application requires.
Moving on, line 15
and onwards is the start of the configuration for deploying your application to your servers. Under the deploy
, we define a separate object for each environment we want for deploys. Under each environment configuration, we have the following keys -
authorized_keys
on your servers. If not already obvious already, doing this is tedious if you have more than 1 server and you have a team working on the application.master
. You can then have origin/staging
for your staging servers etc.logs
folder and create the log file inside the folder.After you have configured the file, save it and exit the editor. In your terminal from the project root folder (or where ever you have placed the .json
file in your project folder), run pm2 deploy ecosystem.json production setup
. The setup
part at the end is for the first time deploys to newly spun up servers. This command will connect to your servers and set up the folders and clone your repo onto your machines.
If you get an error message during the setup process that the connection failed, it is usually due to your server not being able to authenticate the RSA fingerprint of your git servers. To get around it, you can log on to your servers beforehand and clone the repo to a random folder so that the fingerprint gets added to your list of known_hosts
or you can add it yourself to the list if you already know the fingerprints for the git servers.
Lastly, after the setup is done, run pm2 deploy ecosystem.json production
to deploy code to your servers. PM2 will automatically start/restart the applications as defined in your configuration file and if everything goes well, will exit with a SUCCESS message at the end.
Navigate to your application’s URL in the browser and you should see your app running on your newly created servers.