I am using the mand pm2 start apps.json
to start multiple apps in a single mand. These apps are defined in apps.json
:
{
"apps": [
{
"name": "foo",
"script": "./foo.js",
},
{
"name": "bar",
"script": "./bar.js",
},
{
"name": "baz",
"script": "./baz.js",
}
]
}
Question: Is it possible to define the startup sequence, such that foo.js
has to finish starting first before bar.js
and baz.js
can start?
For example, foo.js
can perform a graceful start, running process.send('ready')
to change its pm2 status to online
. Only then will bar.js
and baz.js
be started by pm2. This will be similar to Docker Compose's depend_on
parameter.
I am using the mand pm2 start apps.json
to start multiple apps in a single mand. These apps are defined in apps.json
:
{
"apps": [
{
"name": "foo",
"script": "./foo.js",
},
{
"name": "bar",
"script": "./bar.js",
},
{
"name": "baz",
"script": "./baz.js",
}
]
}
Question: Is it possible to define the startup sequence, such that foo.js
has to finish starting first before bar.js
and baz.js
can start?
For example, foo.js
can perform a graceful start, running process.send('ready')
to change its pm2 status to online
. Only then will bar.js
and baz.js
be started by pm2. This will be similar to Docker Compose's depend_on
parameter.
- there are some questions that affects possible approaches: 1. are their startup sequence sync. or async.; 2. do they expose any ports; 3. are they singleton, i.e. is it safe to assume only 1 of each will be running on a single system. – Eric Wong Commented Sep 25, 2020 at 18:18
2 Answers
Reset to default 4No such thing can be done via the configuration file only, but PM2 has a programmatic api which allows you to perform IPC (Inter-Process munication).
The following methods are the ones to work with :
pm2.list
To list the processes that are running and get their names / IDspm2.launchBus
For the processes that will receive information and react in consequencepm2.sendDataToProcessId
For sending informations to another process
This way you can run multiple scripts and make one wait for another. Once a script recieve a message on the message bus, it can start a process with pm2.start
Here's a piece of PSEUDO-CODE to illustrate my point :
const pm2 = require('pm2');
pm2.connect(() => {
pm2.list(function(err, processes) {
const fooProcess = processes.find(p => p.name == 'foo');
pm2.launchBus((err, bus) => {
bus.on('process:msg', packet => {
if (packet.startBar === true) {
pm.start({ script: 'bar.js' }, (err, apps) => { ... })
}
});
bus.on('error', console.error);
});
});
});
In another script, you would have the following :
pm2.sendDataToProcessId(barProcessID, {
data : { startBar : true },
topic: 'process:msg'
}, (err, res) => console.log(err, res));
Best regards
A little hack, you can write: "start": "pm2 start server.js && pm2 start server1.js"
inside package.json
. If you'd run it as npm start, it'll run the start script, similarly, you can create the script to stop it.
If not then you can also use child_process
[it es by default with nodejs] to run mands from inside your script by using childProcess.exec('pm2 start server.js && pm2 start server1.js');