So this isn't an issue per se but I haven't been able to find data on this and would appreciate the help.
The idea is to run multiple instance of the same app (in fork mode) bound to different ports using pm2, on a single machine. The requests to these apps will be load balanced using nginx as a reverse proxy.
I run the first instance using the following command:
APP_PORT=3000 pm2 start -x ./bin/server --name "app1"
This works fine. But when I do:
APP_PORT=4000 pm2 start -x ./bin/server --name "app2"
I get an error saying:
[PM2] [ERROR] Script already launched, add -f option to force re execution
How do I start multiple instances of the same app bound to different ports on a the same machine using pm2?
Thanks in advance!
If you can live without any feature of pm2, such as monitoring, etc, I would launch each instance isolated from each other (without fork), and use supervisord instead of pm2.
Just my two cents.
If pm2 is incapable of meeting this requirement then I _will_ be switching to a solution like supervisord or monit etc.
The reason I asked this here is because this is a basic requirement when setting up a bunch of instances of a node app to be load balanced by nginx. I know that pm2 can manage load balancing using the cluster module but imho cluster needs a lot of work still and isn't production ready yet.
So yes, if pm2 cannot deliver then supervisord or monit it shall be but I really hope there's a way to do this in pm2.
Facing same issue, though I am using pm2 with cluster mode in production (my application is small). But the problem I face is IF my node servers fail nginx can show a custom page (pages like Sorry we ll be back). But if I use pm2 I can find no way to do this.
I was able to launch multiple instances of the same script using json config:
pm2 start pm2.json
pm2.json:
{
"apps": [
{
"exec_mode": "fork_mode",
"script": "./lib/index.js",
"name": "proj-0",
"node_args": [ "--harmony" ],
"env": {
"PORT": 4001,
"NODE_ENV": "production"
},
"error_file": "/var/www/logs/proj-0.err.log",
"out_file": "/var/www/logs/proj-0.out.log"
},
{
"exec_mode": "fork_mode",
"script": "./lib/index.js",
"name": "proj-1",
"node_args": [ "--harmony" ],
"env": {
"PORT": 4002,
"NODE_ENV": "production"
},
"error_file": "/var/www/logs/proj-1.err.log",
"out_file": "/var/www/logs/proj-1.out.log"
}
]
}
Json is always a better way to declare how your apps should be configured!
With PM2 0.12 you will be able to write json with json5
Closing
Right, I shall try this. Ty @skozin
@Unitech advice taken. And, json5 seems nice but that site has to be one of the most unreadable sites I have come across in a while haha.
@Unitech Can you please elaborate on json5 and how it affects this issue ? I can't find anything like repeating the same config block over and over again with slight variations, as this is what is usually needed in these cases.
Hi,
I am new to nginx and i wanted to load balance my nodejs webapp using nginx and there are various confusing articles about it , is there any stream line walkthrough for nginx + nodejs webapps in localhost based system ?
pm2 clustering is good but when i perform apache benchmark test the result for static content are poor !
cluster screen grab

and apache benchmark screenshot

one workaround that surprisingly worked for me is creating symlinks
I personally run multiple instances of my app in different ports with pm2, i name the instance after the port, like 'myapp:8080' and i have a js loadbalancer and the nginx on lets say por 1337, then the nginx forwards the traffic from the port 80 and serves the static files.

This is the load balancer i created for that, it uses redis to register and unregister servers, feel free to use it.
https://gist.github.com/Zaggen/bbec82153f45ec60a136dca8e9ed65e7
And the nginx config file looks something like this:
server {
listen 80;
listen [::]:80 ipv6only=on;
root /var/www/my-app/.tmp/public;
server_name "";
location / {
try_files $uri @backend;
}
location @backend {
proxy_pass http://127.0.0.1:1337;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Following is necessary for Websocket support
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Here is a really useful tutorial on how to implement clustering in PM2 https://keymetrics.io/2015/03/26/pm2-clustering-made-easy/
馃敘
I was able to launch multiple instances of the same script using json config:
pm2 start pm2.jsonpm2.json:
{ "apps": [ { "exec_mode": "fork_mode", "script": "./lib/index.js", "name": "proj-0", "node_args": [ "--harmony" ], "env": { "PORT": 4001, "NODE_ENV": "production" }, "error_file": "/var/www/logs/proj-0.err.log", "out_file": "/var/www/logs/proj-0.out.log" }, { "exec_mode": "fork_mode", "script": "./lib/index.js", "name": "proj-1", "node_args": [ "--harmony" ], "env": { "PORT": 4002, "NODE_ENV": "production" }, "error_file": "/var/www/logs/proj-1.err.log", "out_file": "/var/www/logs/proj-1.out.log" } ] }
Optimised your answer:
// Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
const app = {
name: "App",
script: "server.js",
args: "one two",
instance_var: "INSTANCE_ID",
log_date_format: "YYYY-MM-DD HH:mm Z",
autorestart: true,
max_memory_restart: "1G"
};
module.exports = {
apps: [
{
...app,
...{
watch: false,
env: {
PORT: 5000,
NODE_ENV: "production"
}
}
},
{
...app,
...{
watch: true,
env: {
PORT: 5001,
NODE_CONFIG_DIR: "",
NODE_ENV: "staging"
}
}
}
],
deploy: {
production: {
user: "node",
host: "212.83.163.1",
ref: "origin/master",
repo: "[email protected]:repo.git",
path: "/var/www/production",
"post-deploy": "npm install && pm2 reload ecosystem.config.js --env production"
}
}
};
Most helpful comment
I was able to launch multiple instances of the same script using json config:
pm2.json: