Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple instance of an app (in fork mode) bound to different ports + load balancing using nginx #765

Closed
zeusdeux opened this issue Oct 9, 2014 · 12 comments

Comments

@zeusdeux
Copy link

zeusdeux commented Oct 9, 2014

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!

@jfhenriques
Copy link

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.

@zeusdeux
Copy link
Author

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.

@faizanahemad
Copy link

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.

@skozin
Copy link

skozin commented Nov 10, 2014

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"
    }
  ]
}

@Unitech
Copy link
Owner

Unitech commented Nov 13, 2014

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

@Unitech Unitech closed this as completed Nov 13, 2014
@zeusdeux
Copy link
Author

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.

@dtouch3d
Copy link

@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.

@matt212
Copy link

matt212 commented Feb 27, 2016

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
screenshot from 2016-02-27 17 57 27
and apache benchmark screenshot
new

@ChStark
Copy link

ChStark commented Jun 29, 2016

one workaround that surprisingly worked for me is creating symlinks

@Zaggen
Copy link

Zaggen commented Mar 16, 2017

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.

pm2

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";
   }
}

@pinich
Copy link

pinich commented Jun 6, 2017

Here is a really useful tutorial on how to implement clustering in PM2 https://keymetrics.io/2015/03/26/pm2-clustering-made-easy/

🔢

@lid3rs
Copy link

lid3rs commented Apr 12, 2019

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"
    }
  ]
}

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"
        }
    }
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests