Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to run multiple nodejs applications (using the express framework) all served on the same external port (80) but each under a subdirectory.

E.g. I want...

NodeJsApplication1 to be available at http://www.mydomain.com/NodeJsApplication1

NodeJsApplication2 to be available at http://www.mydomain.com/NodeJsApplication2

etc.

I have tried using Nginx as a proxy with a conf similar to the following.

server {
    listen       80;
    server_name  www.mydomain.com;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }

    location /NodeJsApplication1/ {
        proxy_pass http://0.0.0.0:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite /NodeJsApplication1/(.*) /$1 break;
    }

    location /NodeJsApplication2/ {
        proxy_pass http://0.0.0.0:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite /NodeJsApplication2/(.*) /$1 break;
    }
}

This works find for accessing the page but it breaks all relative URLs on the returning page. All scripts and css etc are pointing at the root (E.g. www.mydomain.com/styles/main.css).

I know I can use multiple subdomains but don't want to go down that route. I'd prefer to have subfolder proxy so it is all handled in software and I don't need to set up any DNS records for each application.

Is this even possible?

Update

Within the applications themselves all links are using relative paths. For example:

<link href="styles/main.css" />
<script src="scripts/app.js" />

But when rendered the browser treats them as "www.mydomain.com/styles/main.css" rather than "www.mydomain.com/NodeJsApplication1/styles/main.css".

Update 2 I know of two three possible (non-ideal) solutions to this problem.

  • The first being to modify the NodeJS applications to specify a full URL but this requires the application to know the subdirectory that nginx is configured with and it ruins portability to another environment.
  • The second is to use subdomains. This I know works and each application could be set as NodeJsApplication1.mydomain.com and all links will act as expected. The issue I have with this is it requires setting up a DNS record for each application. I want something that could be almost done automatically without much manual work. (A wildcard record is not appropriate as the domain is used for other purposes).
  • Use the <base> tag to specify the root of the application. Again this has the problem of requiring a change to the application rather than the environment.
share|improve this question

4 Answers 4

I had a similar issue with having multiple MEAN apps on the same domain. I wanted subdirectories instead of having to create a new subdomain for each app. In addition to adding a rewrite to your Nginx config:

rewrite ^/app1/(.*)$ /$1 break;

You also need to set your <base> tag in the head of your index:

<base href="/app1/">

from https://www.digitalocean.com/community/questions/how-to-run-multiple-node-application-with-nginx-same-droplet-same-domain

share|improve this answer

Update

As it seems you have nginx proxy working, the problem is in your application using hard-coded links to main domain. This seems like a limitation imposed by an application and nginx can't really help you with that, because there is no way for it to know when you are accessing files like /css/style.css should it redirect it to /NodeJsApplication1 or /NodeJsApplication2.

Old Answer

You cannot have two different applications bind to same port on same system. What you should do instead, is bind them to different ports, and then in your nginx configuration pass to specific application port like this (this asumes you are using 3000 port for app1 and 3001 port for app2):

location /NodeJsApplication1/ {
    proxy_pass http://0.0.0.0:3000;
    ...
}


location /NodeJsApplication2/ {
    proxy_pass http://0.0.0.0:3001;
    ...
}
share|improve this answer
    
Sorry, that was a typo on my part. Both NodeJS applications use a different port. Updated question. –  AverageMarcus Mar 24 at 11:21
    
I have made an update in the answer. The limitation is in NodeJSApplication which hardcodes all URL's to a domain instead of relative path where application is hosted. This is limitation in application and should be fixed there (by altering configuration if possible). It might also be the case that application is not written in such a way to support this. –  edvinas.me Mar 24 at 11:26
    
All links in the application use relative URL, such as <a href="some/path/under/the/application/"> rather than <a href="/root/of/domain/path"> but it seems that when nginx does the internal redirect to the port the application doesn't know that the current directory isn't the root. –  AverageMarcus Mar 24 at 11:33
up vote 0 down vote accepted

So it turns out this was an issue with the NodeJS application itself and not with the environment setup. It seems the application is trying to be clever and get the root of the application but not knowing it is being proxied (or something like that).

When I tried it with a clean barebones application it worked as expected and the relative paths were valid.

share|improve this answer

About the question ,css、js、images files are missed , You can do that

if you use express framework。 you need add this code line

app.enable('trust proxy');

this value 'trust proxy' default value is disable.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.