How to run multiple Node.js servers using Nginx as a reverse proxy
Running multiple Node.js servers using the same port is not possible. My solution to this problem is by using a domain name and Nginx’s reverse proxy configuration to allow multiple Node.js servers to run in the same port.
My configuration looks like this:
Part 1: NodeJS servers
For testing purposes, I’m using this Hello World code and I’ll run this code in 3 instances using ports 3001, 3002, and 3003. Using pm2, I’ll make sure that these 3 apps will autostart. I modified every listening port in the server.js file in every folder of these 3 apps.
server.js
const express = require('express')
const app = express()
app.set('view-engine', 'ejs')
app.get('/', (req, res) => {
res.render('index.ejs')
});
app.listen(3001) // the listening port, 3001 for app1, 3002 for app2, 3003 for app 3
And for testing purposes, I modified every index.ejs title to something like “App 1”, “App 2”, and “App3” just for identification.
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>App 1</title>
</head>
<body>
<h1>NodeJS App 1</h1>
</body>
</html>
And the folder structure looks like this :
NodeJS servers list:
To test that every NodeJS server runs perfectly, use cURL to port 3001, 3002, and 3003.
curl localhost:3001
curl localhost:3002
curl localhost:3003
Output:
Port 3001
<!DOCTYPE html>
<html>
<head>
<title>App 1</title>
</head>
<body>
<h1>NodeJS App 1</h1>
</body>
Port 3002
<!DOCTYPE html>
<html>
<head>
<title>App 2</title>
</head>
<body>
<h1>NodeJS App 2</h1>
</body>
Port 3003
<!DOCTYPE html>
<html>
<head>
<title>App 3</title>
</head>
<body>
<h1>NodeJS App 3</h1>
</body>
Part 2: Nginx reverse proxy server
After testing every server using cURL, I configured the Nginx server blocks using nano
sudo nano /etc/nginx/sites-available/testapp1.gabrielkheisa.xyz
sudo nano /etc/nginx/sites-available/testapp2.gabrielkheisa.xyz
sudo nano /etc/nginx/sites-available/testapp3.gabrielkheisa.xyz
testapp1.gabrielkheisa.xyz
server{
listen 80;
server_name testapp1.gabrielkheisa.xyz ;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
testapp2.gabrielkheisa.xyz
server{
listen 80;
server_name testapp2.gabrielkheisa.xyz ;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
testapp3.gabrielkheisa.xyz
server{
listen 80;
server_name testapp3.gabrielkheisa.xyz ;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3003;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Link these files to the sites-enabled directory
sudo ln -s /etc/nginx/sites-available/testapp1.gabrielkheisa.xyz /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/testapp2.gabrielkheisa.xyz /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/testapp3.gabrielkheisa.xyz /etc/nginx/sites-enabled/
Test the configurations using sudo nginx -t , if there’s no error, continue to restart the Nginx server using sudo systemctl restart nginx.
Part 3: Configure your domain name in your DNS record
Lastly, make sure you already configure your domain name to your A record with the value of the Nginx’s public IP or CNAME domain name.
These are my NodeJS test apps running behind the Nginx reverse proxy:
Reference: