Unitech / pm2

Node.js Production Process Manager with a built-in Load Balancer.
https://pm2.keymetrics.io/docs/usage/quick-start/
Other
41.35k stars 2.61k forks source link

Better support for dotenv in cluster mode ? #5766

Open MonsieurJoyeux opened 7 months ago

MonsieurJoyeux commented 7 months ago

Im trying to setup in production a nodeJs app in cluster mode with a .env file provided. I tried doing so using 2 approaches :

1 ) Using dotenv

I can get it working only if I change my application code adding "require('dotenv').config()". I don't want to delegate this responsability to the code. So I tried using this ecosystem file :

module.exports = {
  apps: [{
    name: 'api-dev',
    script: 'server.js',
    cwd: '/var/node-app/api-dev/current',
    instances: 'max',
    exec_mode: 'cluster',
    log: '/var/log/pm2/api-dev.log',
    error: '/var/log/pm2/api-dev.error.log',
    merge_logs: true,
    node_args: '-r dotenv/config', // launching node with dotenv here
    env: {
      NODE_ENV: 'production',
      DOTENV_CONFIG_PATH: '/var/node-app/api-dev/current/.env', // setting the .env path here
    },
  }],
};

and when I execute "pm2 deploy ecosystem.config.js develop", my apps crash instantly and silently (pm2 logs doesn't log anything which is weird in a first place) I tried to play around with apps[0].env.DOTENV_CONFIG_PATH and apps[0].node_args, and never achieved to have a working clustered env for my app. It either crash or doesn't load env variables.

2 ) Using built-in NodeJS support for .env files

With this config :

module.exports = {
  apps: [{
    name: 'api-dev',
    script: 'index.js',
    cwd: '/var/node-app/api-dev/current',
    instances: 'max',
    exec_mode: 'cluster',
    log: '/var/log/pm2/api-dev.log',
    error: '/var/log/pm2/api-dev.error.log',
    merge_logs: true,
    node_args: '--env-file=.env', // enabling node support for env-file
  }],
};

In a first place it does work. Then I tried to add a second app clustered as well and I noticed something weird aswell : The first app that is launched will successfully load env variables, but all other apps launched after the first wont load them. I had "applicationA" and "applicationB", when I first launch "applicationB" and then "applicationA", I will have 2 nodes working for applicationB and 2 in errors for application A. If I launch application A first, its the other way around.

Im using Node 20.11.0, pm2 5.3.1 on Debian 12 Bookworm

Here is my pm2 reports

--- PM2 report ----------------------------------------------------------------
Date                 : Wed Feb 14 2024 18:47:33 GMT+0100 (Central European Standard Time)
===============================================================================
--- Daemon -------------------------------------------------
pm2d version         : 5.3.1
node version         : 20.11.0
node path            : /usr/bin/pm2
argv                 : /usr/bin/node,/usr/lib/node_modules/pm2/lib/Daemon.js
argv0                : node
user                 : boss
uid                  : 1000
gid                  : 1000
uptime               : 23min
===============================================================================
--- CLI ----------------------------------------------------
local pm2            : 5.3.1
node version         : 20.11.0
node path            : /usr/bin/pm2
argv                 : /usr/bin/node,/usr/bin/pm2,report
argv0                : node
user                 : boss
uid                  : 1000
gid                  : 1000
===============================================================================
--- System info --------------------------------------------
arch                 : x64
platform             : linux
type                 : Linux
cpus                 : Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz
cpus nb              : 2
freemem              : 1336549376
totalmem             : 2026278912
home                 : /home/boss
===============================================================================
--- PM2 list -----------------------------------------------
┌────┬─────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name            │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├────┼─────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 3  │ api-dev         │ default     │ 2.30.0  │ cluster │ 28572    │ 22m    │ 0    │ online    │ 0%       │ 128.8mb  │ boss   │ disabled │
│ 4  │ api-dev         │ default     │ 2.30.0  │ cluster │ 28582    │ 22m    │ 0    │ online    │ 0%       │ 128.4mb  │ boss   │ disabled │
│ 1  │ auth-dev        │ default     │ 2.7.0   │ cluster │ 28486    │ 22m    │ 0    │ online    │ 0%       │ 74.3mb   │ boss   │ disabled │
│ 2  │ auth-dev        │ default     │ 2.7.0   │ cluster │ 28496    │ 22m    │ 0    │ online    │ 0%       │ 75.1mb   │ boss   │ disabled │
└────┴─────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
Module
┌────┬──────────────────────────────┬───────────────┬──────────┬──────────┬──────┬──────────┬──────────┬──────────┐
│ id │ module                       │ version       │ pid      │ status   │ ↺    │ cpu      │ mem      │ user     │
├────┼──────────────────────────────┼───────────────┼──────────┼──────────┼──────┼──────────┼──────────┼──────────┤
│ 0  │ pm2-intercom                 │ 1.0.0         │ 28460    │ online   │ 0    │ 0%       │ 52.4mb   │ boss   │
└────┴──────────────────────────────┴───────────────┴──────────┴──────────┴──────┴──────────┴──────────┴──────────┘
===============================================================================
--- Daemon logs --------------------------------------------
/home/boss/.pm2/pm2.log last 20 lines:
PM2        | 2024-02-14T18:24:29: PM2 log: RPC socket file      : /home/boss/.pm2/rpc.sock
PM2        | 2024-02-14T18:24:29: PM2 log: BUS socket file      : /home/boss/.pm2/pub.sock
PM2        | 2024-02-14T18:24:29: PM2 log: Application log path : /home/boss/.pm2/logs
PM2        | 2024-02-14T18:24:29: PM2 log: Worker Interval      : 30000
PM2        | 2024-02-14T18:24:29: PM2 log: Process dump file    : /home/boss/.pm2/dump.pm2
PM2        | 2024-02-14T18:24:29: PM2 log: Concurrent actions   : 2
PM2        | 2024-02-14T18:24:29: PM2 log: SIGTERM timeout      : 1600
PM2        | 2024-02-14T18:24:29: PM2 log: ===============================================================================
PM2        | 2024-02-14T18:24:29: PM2 log: App [pm2-intercom:0] starting in -fork mode-
PM2        | 2024-02-14T18:24:29: PM2 log: App [pm2-intercom:0] online
PM2        | 2024-02-14T18:24:35: PM2 log: App [auth-dev:1] starting in -cluster mode-
PM2        | 2024-02-14T18:24:35: PM2 log: App [auth-dev:1] online
PM2        | 2024-02-14T18:24:35: PM2 log: App [auth-dev:2] starting in -cluster mode-
PM2        | 2024-02-14T18:24:35: PM2 log: App [auth-dev:2] online
PM2        | 2024-02-14T18:25:11: PM2 log: App [api-dev:3] starting in -cluster mode-
PM2        | 2024-02-14T18:25:11: PM2 log: App [api-dev:3] online
PM2        | 2024-02-14T18:25:11: PM2 log: App [api-dev:4] starting in -cluster mode-
PM2        | 2024-02-14T18:25:11: PM2 log: App [api-dev:4] online
PM2        | {"log.level":"warn","@timestamp":"2024-02-14T17:25:12.396Z","log":{"logger":"elastic-apm-node"},"ecs":{"version":"1.6.0"},"message":"Invalid \"serverUrl\" config value, it must be a valid URL"}
PM2        | {"log.level":"warn","@timestamp":"2024-02-14T17:25:12.485Z","log":{"logger":"elastic-apm-node"},"ecs":{"version":"1.6.0"},"message":"Invalid \"serverUrl\" config value, it must be a valid URL"}

(The app "api-dev" is actually no working since it didn't load the env variables)

Did someone already achieved to launch in cluster mode, multiple nodeJS app with a .env file ? (Thats my first issue I submit, sorry if it isn't clear)

azuisleet commented 7 months ago

If you run in fork mode, this should work correctly.

In cluster mode, the cwd option is not being used, which there is a related issue for https://github.com/Unitech/pm2/issues/5722

wvq commented 6 months ago

node_args: '-r dotenv/config' works for me under pm2 5.3.1 cluster mode. But it needs a clean pm2 daemon. If I stop pm2 stop <app> and restart pm2 start <app>, there is an error says dotenv/config not found, I have to run pm2 kill, then run pm2 start <app> in a new pm2 daemon.