July 12, 2012

Deploy multiple Node applications on one web server in subfolders with Nginx

Things get tricky with Node when you need to move your application from from localhost to the internet.

There is no common approach for Node deployment.

Google can find tons of articles on this topic, but I was struggling to find the proper solution for the setup I need.

Basically, I have a web server and I want Node applications to be mounted to subfolders (i.e. http://myhost/demo/pet-project/) without introducing any configuration dependency to the application code.

At the same time I want other stuff like blog to run on the same web server.

Sounds simple huh? Apparently not.

In many examples on the web Node applications either run on port 80 or proxied by Nginx to the root.

Even though both approaches are valid for certain use cases, they do not meet my simple yet a little bit exotic criteria.

That is why I created my own Nginx configuration and here is an extract:

From this example you can notice that I mount my Pet Project Node application running on port 3000 to http://myhost/demo/pet-project.

First Nginx checks if whether the requested resource is a static file available at /opt/demo/pet-project/public/ and if so it serves it as is that is highly efficient, so we do not need to have a redundant layer like Connect static middleware.

Then all other requests are overwritten and proxied to Pet Project Node application, so the Node application does not need to know where it is actually mounted and thus can be moved anywhere purely by configuration.

proxy_redirect is a must to handle Location header properly. This is extremely important if you use res.redirect() in your Node application.

You can easily replicate this setup for multiple Node applications running on different ports and add more location handlers for other purposes.

UPDATE: Why and how you should do it in subdomains instead.

3 comments:

Unknown said...

Hi Sergey,

thanks a lot, that saved my day!

Gerd

Unknown said...
This comment has been removed by a blog administrator.
Unknown said...

I found this did not work with multiple directories (multiple apps) unless I put all of the locations in the same server.

I first tried separate configuration files in sites-available, one for each app subdirectory, and I would consistently get

Restarting nginx: nginx: [warn] conflicting server name "frontend" on 0.0.0.0:80, ignored
nginx.


With "frontend" the actual hostname of my machine.

When I rewrote a single site configuration file to have one server with several upstream and location blocks, I got it to work.

It might be useful to show how you add "multiple" applications because it would have saved me considerable time if I realized they all had to be the same server.

Also: I appreciated the sub-domain approach, but in my case, that won't work because we can't add the subdomains to our dns, so everything needs to route off the base URL.

Anyway, this was still helpful. Thanks! I just wanted to share my experience in case it helps someone else.