How to run multiple react apps on same domain using nginx

I have two react.js apps running on two different ports. App1 on port 3000 and App2 on port 3001. App2 should be served at http://localhost:8000/nest/dataviewer/2597/data/2490 and App1 should be served in all other cases.

My nginx configuration :

server {
        listen 8000;
        gzip on;
        gzip_types      text/plain application/xml;
        gzip_proxied    no-cache no-store private expired auth;
        gzip_min_length 1000;
        satisfy any;
        index index.html index.htm;
        location ~* (^nest/dataviewer) {
            proxy_pass  http://127.0.0.1:3001;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-for $remote_addr;
           #proxy_set_header X-Forwarded-Proto $scheme;
    }
    location ~*  {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-for $remote_addr;
    }
    }

with the above configurations I’m not able to run the app2 at http://localhost:8000/nest/dataviewer/2597/data/2490:

This is the warning I’m getting and no pages are loaded.

proxyConsole.js:56 Warning: [react-router] Location "/nest/dataviewer/2597/data/2490" did not match any routes


Solution 1:

It looks like your issue is that your react.js app doesn't have a route to handle the path you're sending it:

[react-router] Location "/nest/dataviewer/2597/data/2490" did not match any routes.

If you expect it to be able to handle that path, review your app. If instead, or app is expecting a different path, update your location and proxy_pass directives to send the expected request URI. Take a look at the Nginx proxy_pass document: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:

So lets say your app is expecting "/2597/data/2490". You might try something like this. The trailing slash on the proxy pass is critical here because it will replace the /nest/dataviewer/, ultimately removing it.

location /nest/dataviewer/ {
    proxy_pass http://127.0.0.1:3001/;
}

Note, You'll need to replace your second location with a non-regular expression location, since a matching regular expression will always take priority over any prefix match. If you don't, all requests will be handled by the location ~* block.

The full solution might look like this:

server {
    listen 8000;
    gzip on;
    gzip_types      text/plain application/xml;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;
    satisfy any;
    index index.html index.htm;
    location /nest/dataviewer/ {
        proxy_pass  http://127.0.0.1:3001/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-for $remote_addr;
       #proxy_set_header X-Forwarded-Proto $scheme;
    }
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-for $remote_addr;
    }
}