Deploy and iterate faster, hello ecosystem.json
author Alexandre Strzelewicz, Jun 25th, 2014

ecosystem

We announced it at NodeJS paris meetup (here are the slides) and we did it! For the release of PM2 0.9.x, a new awesome and simple feature will make your life much easier.

We embedded a modified version of deploy from the Node.js Mozart, TJ Holowaychuk and we also refactored the JSON application declaration. Internally it's a simple bash script that doesn't need any external dependencies to be installed.

Here are the features of this embedded deploy system:

$ 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

You can display the PM2 deploy help with:

$ pm2 deploy help

And dont forget that this feature is available on PM2 > 0.9, so update PM2 accordingly.

The ecosystem.json file

Now, a new file called by default ecosystem.json will allow you to declare your applications/services and also the different hosts you want to deploy code into.

You can generate a sample ecosystem.json via the command:

$ pm2 ecosystem

This file will look like this:

{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env": {
      "COMMON_ENV_VAR": "true"
    }
    "env_production": {
      "NODE_ENV": "production",
    }
  },{
    "name"      : "WEB",
    "script"    : "web.js"
  }],
  "deploy" : {
    "production" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "repo" : "git@github.com:repo.git",
      "ref"  : "origin/master",
      "path" : "/var/www/production",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
    },
    "dev" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "repo" : "git@github.com:repo.git",
      "ref"  : "origin/master",
      "path" : "/var/www/development",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
    }
  }
}

There is the apps section that describes your different applications/services to be run and the deploy section that describes where your code should be deployed.

As you can notice, there is also a env_<ENVIRONMENT> attribute that specify dedicated environment variable depending on where you gonna deploy your code.

As always, locally you can launch all theses services via:

$ pm2 start ecosystem.json

Deploy declaration

On each enviroment (production, dev...) there are some attributes configurable like these ones:

key /path/to/some.pem  
user deployer  
host n.n.n.n  
repo git@github.com:visionmedia/express.git  
path /var/www/myapp.com  
ref origin/master  
pre-deploy ./bin/something  
post-deploy /var/www/myapp.com/update.sh  

Customize / add the keys depending on your needs.

Important Note : by default the post-deploy is set with some logic dedicated to PM2. Internally if this attribute is not set, the post-deploy will call pm2 startOrRestart ecosystem.json (startOrRestart)

Configuring deployment

On your target servers you must already have PM2 installed via:

$ npm install pm2@latest -g

At the same time have PM2 be able to start on server startup via:

$ pm2 startup ubuntu

Disconnect from your remote server and make sure that your remote server has your ssh keys. You can generate and copy them via:

$ ssh-keygen -t rsa
$ ssh-copy-id node@myserver.com

Once you have generated the ecosystem.json and edited it accordingly to your needs, you're all set and ready to go!

Setup and Deployment

Setup

Important note: Commit your node_modules folder on your project Git repository. It's a best practice when you deploy code to keep version consistency between all the environments.

First PM2 has to initialize your remote system. To do that:

$ pm2 deploy <environment_key> setup

This will create folders depending on the path attribute
Note: By default PM2 will look for a local ecosystem.json file, if you want to set another file do $ pm2 deploy <ecosystem_file> <environment_key> setup (for instance you can use the package.json instead!)

Deploying

Now PM2 has to grab the latest version of your app and start the applications configured in the ecosystem.json under apps attribute. To do that:

$ pm2 deploy <environment_key>

Done !

Other commands

With the ecosystem.json on the current folder:

# Update the code
$ pm2 deploy <environment_key> update

# Revert to [n] th commit
$ pm2 deploy <environment_key> revert 1

# Execute a command on the server
$ pm2 deploy production exec "pm2 restart all"

Conclusion

Hope this will be helpful to you! Some other links that might interests you:

Cheers!

Tagged in: deployment | pm2 deploy