MEAN Stack : Nginx reverse proxy to a node application server managed by PM2
In this chapter, we'll setup two Node apps on a backend app server. Also, we'll setup an Nginx Reverse Proxy in front of the app server which works as a load balancer.
The apps will be managed by PM2 rather than using a simple forever or nodepmon.
Picture source : How To Set Up a Node.js Application for Production on Ubuntu 14.04
The two machines are:
- App: 172.31.10.18 (private)
- Proxy: 54.183.232.229 (public)
User can get the app by accessing public ip of the proxy server, and this is the default:
The second app can be accessed by http://54.183.232.229/2:
We can see the two apps are running via PM2 list command:
As we can see from the previous section, our two Hello World applications simply return "Hello World 1" or "Hello World 2" to HTTP requests.
HelloJS/hello.js:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World 1\n'); }).listen(8087,'172.31.10.18'); console.log('Server running at http://172.31.10.18:8087/');
HelloJS/hello2.js:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World 2\n'); }).listen(8089,'172.31.10.18'); console.log('Server running at http://172.31.10.18:8089/');
PM2 is a Node Packaged Modules (NPM), and it does the following:
- Keep applications alive forever
- Reload applications without downtime
- Do admin tasks
We can install PM2 on our app server using the following command:
$ sudo npm install pm2 -g
Using pm2 we can start our Node application:
$ pm2 start hello.js
Applications that are running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup:
$ pm2 startup ubuntu
pm2 has other features:
sudo pm2 monit:
Here is our reverse proxy setup, /etc/nginx/sites-available/default:
server { listen 80; server_name 54.183.232.229; location / { proxy_pass http://172.31.10.18:8087; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } location /2 { proxy_pass http://172.31.10.18:8089; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
With the setup, we get the following:
Note that the app server needs the following firewall setup:
Node.JS
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization