Using PM2, how can I deploy my node.js app to multiple environments and ports on the same server?
Asked Answered
S

3

12

I have an ecosystem.json file for my node app that I deploy using PM2.

I've tried configuring it a bunch of different ways, but have not had luck accomplishing my goal which is to:

  • be able to deploy to either production or staging environment (currently both on same server).
  • When deploying to one, the other should stay running as well.
  • The 2 different environments should be on different ports (prod = 8000, staging = 3000)

What happens is whichever deploy command I run first wins.

So if I do pm2 deploy production and then pm2 deploy staging, only the production app/port combo is running on the server, and vice versa if I switch the order.

EDIT: If I use the conf below, there will be 2 apps running in pm2 status, but if I do a netstat, I only see the first one's port. (centos 6)

I feel like I must be missing something obvious. Here's my ecosystem.json file, I have tried it with and without multiple app declarations at the top.

{
  /**
   * Here we declare the apps that must be managed by PM2
   * All options are listed here:
   * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#json-app-declaration
   *
   */
  apps : [
    {
      "name"       : "myapp-staging",
      "script"     : "app.js",
      "instances"  : "1",
      "error_file" : "/var/log/nodejs/myapp.mydomain.com-staging-err.log",
      "out_file"   : "/var/log/nodejs/myapp.mydomain.com-staging-out.log",
      "pid_file"   : "/home/node/myapp.mydomain.com-staging.pid",
      "exec_mode"  : "cluster_mode",
      "env_staging" : {
        "NODE_ENV": "staging", "PORT": 3000
      },
      "env_production" : {
        "NODE_ENV": "production", "PORT": 8000
      }
    },
    {
      "name"       : "myapp-production",
      "script"     : "app.js",
      "instances"  : "1",
      "error_file" : "/var/log/nodejs/myapp.mydomain.com-staging-err.log",
      "out_file"   : "/var/log/nodejs/myapp.mydomain.com-staging-out.log",
      "pid_file"   : "/home/node/myapp.mydomain.com-staging.pid",
      "exec_mode"  : "cluster_mode",
      "env_production" : {
        "NODE_ENV": "production", "PORT": 8000
      }
    }

  ],


  /**
   * PM2 help you to deploy apps over your servers
   * For more help go to :
   * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#deployment-pm2--090
   */
  deploy : {
    production : {
      user : "node",
      host : "node01.mydomain.com",
      ref  : "origin/master",
      repo : "[email protected]:mydomain/mydomain-myapp.git",
      path : "/var/production/myapp.mydomain.com-production/",
      "post-deploy" : "npm prune && npm install -l && pm2 startOrGracefulReload ecosystem.json --env production",
      env  : {
        NODE_ENV: "production",
        PORT: 8000
      }
    },
    staging : {
      user : "node",
      host : "node01.mydomain.com",
      ref  : "origin/master",
      repo : "[email protected]:mydomain/mydomain-myapp.git",
      path : "/var/production/myapp.mydomain.com-staging/",
      "post-deploy" : "npm prune && npm install -l && pm2 startOrGracefulReload ecosystem.json --env staging",
      env  : {
        NODE_ENV: "staging",
        PORT: 3000
      }
    }
  }
}
Shippen answered 28/4, 2015 at 15:15 Comment(0)
S
7

Answering my own question here. Though not a perfect solution, the way I've accomplished this (for now) is by using 2 separate ecosystem.json files, one for each environment. I have ecosystem.json setup for staging and ecosystem-prod.json setup for production.

So now to deploy to staging I do a standard: pm2 deploy staging and for production I do a slightly more wordy: pm2 deploy ecosystem-prod.json production

Obviously not ideal, but until someone tells me otherwise, might be the only way to do it on the same box with different ports.

Shippen answered 28/4, 2015 at 17:0 Comment(1)
I reached the same conclusion and would look forward to finding a better solution. Advantage is to have the names appear in pm2 listing with different names. E.g. app-staging and app-prodKosel
K
1

You can use a shell environment variable and then use javascript inside the pm2 configuration file. For example if your configuration file has ...

    "apps": [
    {
        "script": "app/server.js",
        "PORT" : process.env.NODE_ENV == "development" ? 8888 : 9999,
        "name": "MemsharpWeb-" + process.env.NODE_ENV,

And you run pm2 from the command line like this

   NODE_ENV=production pm2 start config.json

the port number will be set to 9999.

Kosel answered 8/7, 2016 at 23:26 Comment(0)
R
0

What is your version of nodejs?
I can see that you are operating pm2 in cluster mode with 1 instance.
Pm2 in cluster mode uses custer module of nodejs which is not very effectively developed till version 0.12.x.
If that is the case, your node version < 0.12.x then this is a known issue.

Upgrade your node version and problem will be solved.

Resinate answered 1/6, 2016 at 5:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.