Use dotenvx with PM2

Use dotenvx with PM2

Initial setup

Generate an ecosystem.config.js file.

pm2 init

Modify it to your needs. Something like this.

ecosystem.config.js

module.exports = {
  apps : [{
    script: 'index.js',
    watch: '.'
  }]
};

Your index.js file should look something like this.

index.js

// index.js
const PORT = process.env.PORT || 3000
const http = require('http')
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(`Hello ${process.env.HELLO}`)
});

server.listen(PORT, () => {
  console.log(`Server running on port:${PORT}/`);
});

Run dotenvx

Add @dotenvx/dotenvx and pm2 as dependencies.

npm install @dotenvx/dotenvx --save
npm install pm2 --save

Then, in your package.json, modify your start script.

package.json

{
  "scripts": {
    "start": "dotenvx run -- pm2-runtime start ecosystem.config.js --env production"
  },
  "dependencies": {
    "@dotenvx/dotenvx": "^0.26.0",
    "pm2": "^5.3.0"
  }
}

Create a .env file in the root of your project.

.env

# .env
HELLO="World"

Inject your env using your start script – which is using dotenvx and pm2.

npm start
localhost:$PORT

Your app will say Hello World. The values from your .env file were successfully injected into your env. That covers local development. Let's solve for production next.

Add production environment

Create a .env.production file in the root of your project.

.env.production

# .env.production
HELLO="production"

Modify your start script to load your .env.production file.

package.json

{
  "scripts": {
    "start": "dotenvx run --env-file=.env.production -- pm2-runtime start ecosystem.config.js --env production"
  },
  ...
}

Your app will say Hello production, simulating production. Solid.

localhost:$PORT