0

I have multiple single page applications running each in their own container under the home directoy which is quite straight forward.

Now I would like to route to those applications under the same dns entry using different paths, e.g.:

domain.com      -> defaultAppContainer
domain.com/app1 -> container1
domain.com/app2 -> container2

I do not have the option to rewrite the paths during routing, so I would like for Nginx to listen to the path /app1 or /app2 respectively and serve the applications correctly from there. Currently everything I have tried results in an error.

I have considered two possibilities:

  • Proxying the sub path to home using something like
    location /app1 {
      proxy_pass $host/;
    }
    
    But this does not seem to work for the frontend, I assume some paths are messed up in the request.
  • Serving all files under the sub route, e.g.:
    location /app1 {
      alias root /usr/share/nginx/html/;
    }
    
    Where the alias points to the base dir of the built web app. This gives me a CONN_RESET error.

Also simply redirecting with a 307 is not an option as that would lead to the client calling the base url without the path, which is then routed to the default app.

masus04
  • 121
  • 4

1 Answers1

1

Generally running the app under an URI prefix when the app itself does not expect it is a tricky thing, and the only reliable solution would be to fix/setup the app making it generate all the assets/routes links either relative or including the prefix it is deployed under. Almost every existing workarounds are to rewrite the application responses "on-the-fly" replacing generated links with the new ones. Some kind of a generic answer is here, some additional considerations can be found here.

However if it is a really SPA, lets say a React app that uses something like HashRouter rather than BrowserRouter, a workaround based on the conditional rewrite according to the request Referer HTTP header is possible:

server {
    ...
    if ($http_referer ~ ^https?://yourdomain.com/app1/) {
        rewrite ^ /app1$uri;
    }
    if ($http_referer ~ ^https?://yourdomain.com/app2/) {
        rewrite ^ /app2$uri;
    }
    ...
    location /app1/ {
        proxy_pass http://container1/;
    }
    location /app2/ {
        proxy_pass http://container2/;
    }
}

All the trailing slashes used here are used on purpose, removing any of them will break the solution!

This is not applicable for anything else than SPA (including applications that are using "virtual" routing based on the HTML5 browser history API) since the rewrite logic will be broken after the very first page-to-page transition.

Ivan Shatsky
  • 2,360
  • 2
  • 6
  • 17
  • Thanks a lot for your reply! All Applications are implemented using one of the following: react, vuejs or Flutter, but this is where the guarantees end and I don't have control over the exact implementations. Also, what is the exact function of the rewrites? – masus04 May 17 '22 at 22:24