Deployment System
PM2 features a simple but powerful deployment system that allows to provision and update applications in production environment. This is great when you want to deploy applications on a baremetal server in one or many servers at once.
> pm2 deploy <configuration_file> <environment> <command>
Commands:
setup run remote setup commands
update update deploy to the latest release
revert [n] revert to [n]th last deployment or 1
curr[ent] output current release commit
prev[ious] output previous release commit
exec|run <cmd> execute the given <cmd>
list list previous deploy commits
[ref] deploy to [ref], the "ref" setting, or latest tag
Deployment Configuration
To configure the deployment system, add a deploy
attribute to the Application Configuration File:
module.exports = {
apps : [{
script: 'api.js',
}, {
script: 'worker.js'
}],
// Deployment Configuration
deploy : {
production : {
"user" : "ubuntu",
"host" : ["192.168.0.13", "192.168.0.14", "192.168.0.15"],
"ref" : "origin/master",
"repo" : "git@github.com:Username/repository.git",
"path" : "/var/www/my-repository",
"post-deploy" : "npm install"
}
}
};
Note: make sure the application configuration file in the local folder is named either ecosystem.config.js or pm2.config.js, so you don’t need to type the configuration filename for each command.
Provision remote server
Before provisioning remote server verify that:
- Remote servers have PM2 installed
- Remote servers have granted permissions to GIT clone the target repository
Once remote servers have been configured you can start provisioning them:
$ pm2 deploy production setup
Note: as the app configuration file is named ecosystem.config.js or pm2.config.js in the local folder, you do not need to specify the filename each time
Deploy application
Once the remote server have been provisioned you can now deploy the application:
$ pm2 deploy production
Note: if git report an error that there are local changes but still want to push what is on the remote GIT, you can use the --force
option to force deployment.
Rollback to previous deployment
If you need to rollback to previous deployment you can use the revert
option:
# Revert to -1 deployment
$ pm2 deploy production revert 1
Execute a command on each server
To execute a one-time running command you can use the exec
option:
$ pm2 deploy production exec "pm2 reload all"
Specifics
Deployment Lifecycle
When deploying with PM2, you can specify what do before/after setup and before/after update:
"pre-setup" : "echo 'commands or local script path to be run on the host before the setup process starts'",
"post-setup": "echo 'commands or a script path to be run on the host after cloning the repo'",
"pre-deploy" : "pm2 startOrRestart ecosystem.json --env production",
"post-deploy" : "pm2 startOrRestart ecosystem.json --env production",
"pre-deploy-local" : "echo 'This is a local executed command'"
Multi host deployment
To deploy to multiple hosts in the same time, you just have to declare each host in an array under the attribute host
.
"host" : ["212.83.163.1", "212.83.163.2", "212.83.163.3"],
Specifying SSH keys
You just have to add the “key” attribute with path to the public key, see below example :
"production" : {
"key" : "/path/to/some.pem", // path to the public key to authenticate
"user" : "node", // user used to authenticate
"host" : "212.83.163.1", // where to connect
"ref" : "origin/master",
"repo" : "git@github.com:repo.git",
"path" : "/var/www/production",
"post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
},
Troubleshooting
SSH clone errors
In most cases, these errors will be caused by pm2
not having the correct keys to clone your repository. You need to verify at every step that the keys are available.
Step 1
If you are certain your keys are correctly working, first try running git clone your_repo.git
on the target server. If it succeeds, move onto the next steps. If it failed, make sure your keys are stored both on the server and on your git account.
Step 2
By default ssh-copy-id
copies the default identity, usually named id_rsa
. If that is not the appropriate key:
ssh-copy-id -i path/to/my/key your_username@server.com
This adds your public key to the ~/.ssh/authorized_keys
file.
Step 3 If you get the following error:
--> Deploying to production environment
--> on host mysite.com
○ hook pre-setup
○ running setup
○ cloning git@github.com:user/repo.git
Cloning into '/var/www/app/source'...
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and that the repository exists.
**Failed to clone**
Deploy failed
…you may want to create a ssh config file. This is a sure way to ensure that the correct ssh keys are used for any given repository you’re trying to clone. See this example:
# ~/.ssh/config
Host alias
HostName myserver.com
User username
IdentityFile ~/.ssh/mykey
# Usage: `ssh alias`
# Alternative: `ssh -i ~/.ssh/mykey username@myserver.com`
Host deployment
HostName github.com
User username
IdentityFile ~/.ssh/github_rsa
# Usage:
# git@deployment:username/anyrepo.git
# This is for cloning any repo that uses that IdentityFile. This is a good way to make sure that your remote cloning commands use the appropriate key