PM2 — Create Multiple Environments in Process File (JSON/JS/YAML)

PM2 gives you the opportunity to create advanced application configurations, also known as a process file or ecosystem file. Within those process files, you can define environment variables and make them only available to the related application. Even further, PM2 provides the feature to create multiple environments with completely different values.

This guide shows you how to create and benefit from multiple application environments within a process file.

PM2 Series Overview

Create Multiple Environments in a Process File

Depending on your application setup and execution context you want to make use of different values within your process specific environment variables. Environment variables are a convenient and commonly used way to inject context specific options to your app like

  • the port on which you want your app to run
  • being in „development“ or „production“ mode
  • passing database credentials like username and password

No limits for your configurations! The following exemplary process file defines four different environments, each having their own key-value-pairs: env, env_develop, env_production, env_test. Environments in a PM2 process file follow the schema of env_* where * is the placeholder for your desired environment name.

This tutorial uses the JSON format for the process file. You can certainly map the JSON format to JavaScript or YAML files. For a handy reference, we call the following process file app.json.

app.json

{
  "apps": [
    {
      "name"           : "futurestudio-homepage",
      "script"         : "./server.js",
      "exec_mode"      : "cluster",
      "instances"      : 2,
      "env": {
        "DB_USER"      : "root",
        "DB_PASS"      : "root"
      },
      "env_develop": {
        "NODE_ENV"     : "develop"
      },
      "env_production" : {
        "NODE_ENV"     : "production",
        "PORT"         : 2000,
        "DB_USER"      : "username",
        "DB_PASS"      : "secret-password"
      },
      "env_test"       : {
        "NODE_ENV"     : "testing",
        "PORT"         : 8000
      }
    }
  ]
}

Besides the attributes for name, script, exec_mode and instances, you can spot the individual environment configurations. The values within env are set as the default environment. Make sure to override the default values if necessary in other environments. We’ll get back to this point in a later section of this guide.

Different environments within a PM2 process file are defined using the env_* keyword and replacing the star * with the appropriate name, like env_production. You can define as many different environments as you want by using differing names.

Alright, let’s start a process within a specific environment.

Start Process in a Selected Environment

With multiple environments set up in your process file you can choose the one to start by adding the --env <environment> to the start command that references the process file.

Using the app.json file from above, you’d start the development environment like this:

$ pm2 start app.json --env develop

Within your application running in develop mode, the NODE_ENV variable is now accessible with the value develop (as defined). If you’d add more environment variables for env_develop within the process file, they’ll be exposed to your app as well.

Assuming that you want your app to just start in default mode, you can still reference the app.json file with the PM2 command line utility and only the values defined within env are passed and accessible by your application.

$ pm2 start app.json
# will start your app using "env"

Starting your application with default values makes sense for development or testing purposes avoiding the extra typing to specify the environment.

Switch Environments

In the example above, you’ve started a new app into your selected environment. What if you’ve an existing process managed by PM2 and you want to switch to another environment? That’s straight forward: act on your process and also use the --env <new-environment> argument with the new environment.

Did you start your application in develop first and want to switch to production? Just do it:

$ pm2 restart app.json --env production
# you can also use "reload" or any related PM2 command

Besides pm2 restart, you can leverage every available command like reload to switch environments in zero-downtime manner.

Be Careful With Default Values in env

You know that different environments are indicated by env_*where the star represents the actual environment name. If you define key-value-pairs within env in your process file, those variables and their values are taken as default. Every other environment will have those values set already.

That means, if the default values don’t fit for another environment, you need to either override them or don’t even set them as default. Related to the app.json from above, if you don’t want the DB_USER and DB_PASS values to be set in env_develop and env_test, you need to set them in their specific environment configuration or completely remove them from env. Such values won’t get reset by skipping them in any env_*.

Outlook

PM2 process files offer a convenient way to specify configurations for multiple environments. Use different environments to define the necessary values for the context of your app. If you’re using PM2 during development and production where both setups rely on completely different environment variables, define each context once and use them appropriately.

Be careful with default values defined within env. Those key-value-pairs are passed to each environment.

Do you have further questions on PM2 or Node.js in general? Just let us know on Twitter @futurestud_io or leave a comment below.

Make it rock & enjoy coding!

Explore the Library

Find interesting tutorials and solutions for your problems.