Pm2: Allow override of settings in processes.json using CLI parameters

Created on 9 Jun 2015  路  13Comments  路  Source: Unitech/pm2

This is a feature request (I presume). :-)

I think, having the ability to override values of processes.json would allow flexibility of CI scripting. For example:

pm2 start processes.json --name my-app

This could override the app's name during launch while keeping other configurations in place. With this, I can store a common processes.json and during launch in our servers, can append the app name based on the environment.

This would allow cleaner process management where multiple instances of same app is running in a single server.

Most helpful comment

If you use the xxx.config.js format instead of static JSON or YAML, you can add some dynamic behavior that might address the need. For instance, the following script changes behavior based on the NODE_ENV setting when pm2 is invoked:

pm2.config.js (note that it must end in .config.js):

const production = process.env.NODE_ENV === 'production';

module.exports = {
  apps: [
    {
      name: 'pm2dynconfig',
      script: 'app.js',
      instances: production ? 4 : 1,
      exec_mode: production ? 'cluster' : 'fork',
      watch: !production,
      env: {
        'PORT': production ? '80' : '8000',
        'GREETING': (production
          ? 'Welcome to SuperCoolApp.com'
          : 'SuperCoolApp.com development server'),
      },
    },
  ]
}

All 13 comments

:question: :tired_face:

I think, this could become pretty messy. Since a processes.json file can contain multiple app/process declarations with each individual names and configuration. You had to also pass along, what process declaration you want to have overwritten.

Now that you speak of multi process jsons, it makes sense that the CLI commands can become quite messy.

Nevertheless, from a feature perspective this should be very handy. Think about how all base configurations can be defined in JSON and individual ones be overridden based on the environment / deployment server.

+1 @m-reiniger, we can't really override when a process contains multiple app/process. We can't know which one you'd want to reset.

@shamasis to write json configuration based on an environnement variable you can do:

{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env_staging": {
      "NODE_ENV": "staging"
    },
    "env_production" : {
      "NODE_ENV": "production"
    }
  }]
}

Then you can call pm2 start --env staging to start the one with staging variables.

You can also use tricks like this one with jq:

jq --arg version $new '. + {"version": $version}' package.json > package.tmp.json 

This changes the version in a package.json but could be used to change the name on the fly.

From what I can make out, the env option can only be used to set environment variables, not to configure pm2 options, so this isn't really a solution.

So, if I wanted my development environment to run only 2 instances, but staging and production to 8, I can't configure that in the config file like so

{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env_development": {
      "instance": 2       // this won't make any difference
    },
    "env_production" : {
      "instances": 8    // neither will this
    }
  }]
}

Nah you can't do that.

Yep, seems like the only way is to have separate config files for each environment. I named the config jsons after the environment, and used that to use the correct config in my tests

pm2 start ${NODE_ENV:="development"}.json

+1 this becomes crazy when you have daemons + applications kicking off in a number of different environments. You wind up with dozens of JSON files instead of a handful.

A really good way to do this would've been to have the apps config namespace stay as an Object instead of an Array, where the key is the name of the app.

Example:

{
  "app1": {
    "instances": 2
  },

  "app2": {
    "instances": 4
  }
}

Then from the CLI you can specify the app in a comma delimited format:

pm2 restart config.json --app=app1;

No app specified? Load them all. Comma delimited to pick and choose.

It seems to me like allowing arbitrary overrides of top-level pm2 properties inside the env*: {} would accomplish the goals nicely wouldn't it? This would allow one json file that can run the same configuration with different pm2 'App Name' based on the environment being targeted ...

If you use the xxx.config.js format instead of static JSON or YAML, you can add some dynamic behavior that might address the need. For instance, the following script changes behavior based on the NODE_ENV setting when pm2 is invoked:

pm2.config.js (note that it must end in .config.js):

const production = process.env.NODE_ENV === 'production';

module.exports = {
  apps: [
    {
      name: 'pm2dynconfig',
      script: 'app.js',
      instances: production ? 4 : 1,
      exec_mode: production ? 'cluster' : 'fork',
      watch: !production,
      env: {
        'PORT': production ? '80' : '8000',
        'GREETING': (production
          ? 'Welcome to SuperCoolApp.com'
          : 'SuperCoolApp.com development server'),
      },
    },
  ]
}

@cdbennett did you have to start pm2 with env NODE_ENV=production pm2 start xxx.config.js to get this to work or do you have an easier way to start pm2 without having to prepend it with env NODE_ENV=production?

@jmordica You have a good point. Yes, you could use something like env NODE_ENV=production pm2 start xxx.config.js. You could pass other things via the environment as well and make the config script behave differently based on them.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rangercyh picture rangercyh  路  4Comments

ldarren picture ldarren  路  3Comments

psparago picture psparago  路  3Comments

morfies picture morfies  路  3Comments

lefam picture lefam  路  3Comments