Here's the setup I'm thinking about.
All my apps run under ubuntu user app.
The pm2 startup script is configured with USER app.
app1 needs node 0.10
app2 needs node 0.12
I do the following
cd app1
nvm use 0.10
npm install -g pm2
pm2 start app.js --name "app1"
cd app2
nvm use 0.12
npm install -g pm2
pm2 start app.js --name "app2"
pm2 list lists both of the apps. If I inspect process.version in each of the apps - they're running the correct node version.
Is this a reasonable approach?
It might. The only thing that nvm use 0.12 is doing is that it changes the node binary path so this will definitely work.
I think that changing the interpreter should work too (can't test right now):
$ pm2 start app.js --name app1 --interpreter=~/.nvm/versions/node/v0.12.0/bin/node
One of the advantage of this is that it can easily be reproduced in a json file:
[{
name: "app1",
exec_interpreter: "~/.nvm/versions/node/v0.11.0/bin/node"
},{
name: "app2",
exec_interpreter: "~/.nvm/versions/node/v0.12.0/bin/node"
}]
Works like a charm! The --interpreter option is neat since that way the option is persisted (or can be configured in the json file as you've mentioned).
Also the --interpreted way is better since I can always execute pm2 with node 0.12 and only use --interpreter to point to node 0.10 for the app. Whereas in my example above, I'm running pm2 commands with different version of node for each app (which is probably fine, but a bit weird).
Glad I helped.
It's not weird, pm2 is basically forking搂 your app, I don't know what clustering would be in this scenario.
搂 Just like you do in the shell node app.js #where node can be any binary you want.
Yeah, the forking makes sense.
But in my first example I'm running ~/.nvm/v0.10.36/bin/pm2 start app1 and then ~/.nvm/versions/node/v0.12.0/bin/pm2 app2 and later ~/.nvm/versions/node/v0.12.0/bin/pm2 list, etc. Basically I'm using 2 different versions of pm2 on 2 different versions of node to manage processes on 1 machine, that seems slightly risky since the 2 versions of pm2 might be different (depending on when I npm installed them) and there might be some incompatibilities between running them on node 0.10 and 0.12..
Which is why I prefer the --interpreter approach since I can always using the same pm2 for managing my processes.
Anyways, thanks for your help!
Has this been tested to correctly fork the right Node version during the pm2 startup process?
It does. At least in my setup where i start apps using a json manifest i.e. pm2 start app.json, where app.json contains the exec_interpereter option.
But cluster mode is not work.
I can second that. This is broken for cluster mode.
double checked.
nvm(ized) 6.2.0 node and 5.6.0 are my playpartners.
Tried the @soyuka method but is broken for me. app go to error without logs
It is now available with the latest PM2 version:
{
apps : [{
name : 'API',
script : 'api.js',
interpreter : '[email protected]'
}]
}
https://github.com/Unitech/pm2/blob/master/test/fixtures/nvm-node-version/ecosystem.json#L12
This definitely works!
Thanks
I haven't got [email protected] to work with nvm. Where does pm2 looks for the nvm version of node? I also tried giving it an absolute path node /home/ubuntu/.nvm/vx.x.x/bin/node and was unsuccessful
@danielduhh See by yourself here, you the NVM_DIR to be defined in your path.
Does this work for cluster mode as well?
@geronime
PM2][WARN] Choosing the Node.js version in cluster mode is not supported
!!! TO ANYONE WHO FINDS THIS THREAD !!!
You need to give an absolute path to the --interpreter option (it does not resolve the ~)
EXAMPLE: --interpreter=/home/user/.nvm/v0.10.28/bin/node
You should just define the NVM_DIR and then use [email protected]
Thanks, can you show an example? And how it would work with NODE_ENV=
@GenericUK
NVM_DIR=/path/to/.nvm/ pm2 start pm2.json
pm2.json
[{
"name": "app-name",
"exec_interpreter": "[email protected]",
"script": "server.js",
"interpreter_args": "--harmony"
}]
Thanks, here's my startup for Ghost Blog Running PM2 in node current on NVM and older version of node for Ghost Blog. As it's running an a Raspberry Pi I've disabled logging to ease wear on the SD card.
NVM_DIR=~/.nvm NODE_ENV=development pm2 start ghost/index.js --name "GhostBlog" [email protected] -o "/dev/null" -e "/dev/null"
pm2 only work with nvm alias default
nvm use X && pm2 start doesn't use X node to run app
pass exec_interpreter is okay, but what if we need cluster mode ?
If I'm trying to run a _really_ old app (runs under Node v0.8.18!) in a time before pm2 existed, willpm2 still work?
If you use NVM you install PM2 under the latest Node then you can run your app in older Node using the interpreter argument (see my example above). You just need to make sure nvm current is latest node (the node version PM2 was installed under) when you run PM2
@GenericUK thanks. Yeah, that's what I tried first, but it hasn't been working, so I thought maybe it was because of how old my app was...
I figured it out! It turns out that the setTimeout().unref() function was not added until node v0.9.1 and since the pmx package used by pm2 uses the unref() function, I think it may not be possible to use pm2 to run node apps that require node <0.9.1.
In my particular case, it was the app's reliance on [email protected] that was causing the problem. I didn't write the original app, but eventually I figured out that using a different version of bcrypt would be perfectly satisfactory.
Do you think I should open up a separate issue to describe this particular situation?
@morphatic Sorry but we don't support node under 0.12 and soon we will also drop the support for 0.12
Am I wrong or --interpreter does not override ecosystem definition?
I think it should.
And can I pass x or + like [email protected] or node@8+?
--interpreter=<absolute nvm node binary path> is not working with ecosystem even when no interpreter or exec_interpreter is define inside that ecosystem.
PM2 just ignores the interpreter and looks for /usr/bin/node
I ran pm2 unstartup && pm2 startup, run my systemd command, started PM2 2.11.3 again and nothing happened
Just reported on https://github.com/Unitech/pm2/issues/3639
having NVM_DIR defined, i successfully ran pm2 start bin/www --name app_name --interpreter [email protected]
Is there any difference between interpreter and exec_interpreter?
@GenericUK
NVM_DIR=/path/to/.nvm/ pm2 start pm2.jsonpm2.json
[{ "name": "app-name", "exec_interpreter": "[email protected]", "script": "server.js", "interpreter_args": "--harmony" }]
not work for me.
I don't know why pm2 still uses current node version instead of interpreter.
this is my case:
pm2's current node version: v10.23.0
program required node version: v8.17.0
ecosystem.json
{
"apps": [{
"name": "login-api",
"watch": [ "app.js", "config", "public" ],
"watch_options": {
"usePolling": true,
"followSymlinks": true
},
"interpreter": "[email protected]",
"exec_interpreter": "[email protected]",
"interpreter_args": "--harmony",
"instance_var": "INSTANCE_ID",
"env": {
"NODE_ENV": "production"
},
"exec_mode": "fork",
"cwd": "current",
"script": "./app.js",
"error_file": "../log/app-error.log",
"out_file": "../log/app-out.log"
}]
}
app-error.log
SyntaxError: Unexpected token import
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:617:28)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3
/Users/CyrusNG/.nvm/versions/node/v10.23.0/lib/node_modules/pm2/lib/ProcessContainerFork.js:30
import(url.pathToFileURL(process.env.pm_exec_path));
^^^^^^
@CyrusNG have same error.
@shinebayar-g I am using [email protected]. And I tried following commands:
nvm use 8
pm2 update
then:
node@10's programs in pm2 will be from 'online' to 'errored' status
node@8's programs in pm2 will be from 'errored' to 'online' status
See this. https://github.com/Unitech/pm2/issues/4877 I think yours is same ?
import is experimental in node see https://nodejs.org/api/esm.html maybe that you want to use typescript or babel ? see https://pm2.io/docs/runtime/integration/transpilers/
I can confirm (different app/setup) that specifying the node version in the config file works for fork but not cluster at the moment.
Most helpful comment
It might. The only thing that
nvm use 0.12is doing is that it changes the node binary path so this will definitely work.I think that changing the interpreter should work too (can't test right now):
source
One of the advantage of this is that it can easily be reproduced in a json file: