Unitech / pm2

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

Several PM2 web apps with NGINX #5365

Open jfoclpf opened 2 years ago

jfoclpf commented 2 years ago

I have several NodeJS web apps running in localhost in different ports through PM2. I then use NGINX as web server.

I read the PM2/Nginx production setup for NGINX configuration

upstream my_nodejs_upstream {
    server 127.0.0.1:3001;
    keepalive 64;
}

server {
    listen 443 ssl;

    server_name www.my-website.com;
    ssl_certificate_key /etc/ssl/main.key;
    ssl_certificate     /etc/ssl/main.crt;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_pass http://my_nodejs_upstream/;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }
}

My questions are:

A) is there any further optimizations I can do in NGINX considering I have several NodeJS web apps running under PM2?

B) Can I load balance between different ports for the same app, considering the app runs in different instances?

AxeemHaider commented 2 years ago

If you are using same app in different port for load balancing then there is better option use PM2 with cluster mode, it will handle everything for you

jfoclpf commented 2 years ago

If you are using same app in different port for load balancing then there is better option use PM2 with cluster mode, it will handle everything for you

In PM2 cluster mode, shall I use each instance with different port and then load balance also with Nginx? Or it suffices all the instances with the same port and rely only on PM2 load balancing?

AxeemHaider commented 2 years ago

NodeJS is single thread, so it use only one process when you run cluster mode you specify how many process it take to run on max use pm2 start app.js -i 0 It will run your app in different process but with same port, and it will automatically do the load balancing for you.

in short just run your app in cluster mode on same port and pm2 will handle everything.

jfoclpf commented 2 years ago

That's what I do right now, but I see that some people on the web use different approaches, using also NGINX load balancing, for example, PM2 in cluster mode, but each instance on different ports (ex: 4 instances on ports 3000 till 3003), and then load balancing in NGINX

module.exports = {
  apps : [
      {
        name: "myapp",
        script: "./app.js",
        instances: 4,
        exec_mode: "cluster",
        watch: true,
        increment_var : 'PORT',
        env: {
            "PORT": 3000,
            "NODE_ENV": "development"
        }
      }
  ]
}
upstream my_nodejs_upstream {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
    keepalive 64;
}

server {
    listen 443 ssl;

    server_name www.my-website.com;
    ssl_certificate_key /etc/ssl/main.key;
    ssl_certificate     /etc/ssl/main.crt;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_pass http://my_nodejs_upstream/;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }
}
AxeemHaider commented 2 years ago

You are running in cluster mode exec_mode: "cluster" and using only "PORT": 3000 other ports will not work in nginx 3001, 3002, 3003 Cluster mode will not automatically run your program in different ports. PM2 use NodeJs Cluster you can read about it.

That's totally ok if you want to run your app in different port and use Nginx load balancing. You have to do manual work. But if you use just PM2 cluster mode that's all you need and this will give you some extra features for example if you updating your application pm2 not update it on all process at once but one by one to give you 100% uptime.

According to me both are good, choice is your.

jfoclpf commented 2 years ago

PM2 Cluster mode will run in different ports because you have increment_var : 'PORT'

AxeemHaider commented 2 years ago

Oh, I did not see it

jfoclpf commented 2 years ago

No problem :) I must confess I just found that odd feature very recently also