Run Multiple Node Apps on One Server with Sub-URIs and

I spend hours googling shit to find this easiest way.

What I wanna do is:

Say I have my node app running on port 3000.

  1. Instead of visit, I wanna to visit
  2. So I can visit another app by


[ ] Get my node app and NginX ready.
[ ] Set a sub URI to proxy to our node app.
[ ] Create NginX upstream to handel all the sockets connection.
[ ] Change some app code to match this scheme.
[ ] Since we can only have one socket port on our server, we must seperate different apps by different socket io name space (nsp);
[ ] Moreover, socketio will nolonger share the same port with express app.

Before I find this, I tried Passenger + Apache, Passenger + NginX. The problem I encountered was They just don’t work well with, and saying I must change my router blah blah.

This documentation will focus on Debian 9.0 + NginX 1.10.3

Get my node app and NginX ready.


Set a sub URI to proxy to our node app.

In my case, my app is called bully and my domain name is

For the convenience of managing multiple apps, we can create config files respectively.

In Debian, the location to put config files is /etc/nginx/sites-enabled/.

We need root to edit file here.

sudo vim /etc/nginx/sites-enabled/bully.conf
server {
    listen 80;

    location ^~ /bully/ {
        rewrite ^/bully/(.*)$ /$1? break;
        proxy_set_header Host $host;

This means, when user visits, pass all the traffic to localhost:8888, which my bully app is listening.

After this, I can see my app by visiting However, the still doesn’t work.

Get to work.

If you were serving client socketio script by node,

# in public/index.html
<script src="/"></script>

you will see this error:

# Error
GET net::ERR_ABORTED 502 (Bad Gateway)

Because of Nginx sub URI, this no longer works.

I chose a workaround by pointing the source file to a cdn:

# inside public/index.html
<script type="text/javascript" src=""></script>

Then a 2nd error:

Cannot GET /

It cannot talk to our server.

Let’s say, instead of using the same port with express app, we give one port, say 5000, to all the socketio instances.

Then all our app will talk through port 5000, but in different namespaces.

Creat a upstream at port 5000;

# Add this inside http{} of file /etc/nginx/nginx.conf

upstream socketio {
    # you can do load balance here if you will

route all socketio to this up stream:

# Add this inside server{} of file /etc/nginx/sites-enabled/bully.conf
    location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://socketio/;

Inside server.js, tell to listen to port 5000 with a unique namespace, which we call bullySocket;

const io = require('').listen(5000);
const web = io.of('/bullySocket');

Inside public/index.js, tell socket to connect to this special name space.

let socket = io.connect('');

restart NginX and you node app.

Now it works like a charm!

Leave a Reply

Your email address will not be published. Required fields are marked *