Score:0

NginX: Serve application under sub path

tn flag

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.

Score:1
gr flag

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.

masus04 avatar
tn flag
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?
Score:0
gr flag

Here there is an example how you can deploy multiple angular/react/vue.js apps and an API to separate path and serve them through Nginx:

server{
        server_name yourdomain.com;

        location /api{
                proxy_pass          http://127.0.0.1:8080;
                proxy_http_version  1.1;
                proxy_set_header    Upgrade             $http_upgrade;
                proxy_set_header    Host                $host;
                proxy_set_header    X-Real-IP           $remote_addr;
                proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /admin {
                alias /data/app/ui/admin;
                index index.html index.htm;
                try_files $uri $uri/ /admin/index.html;
                }
    location /client {
                alias /data/app/ui/client;
                index index.html index.htm;
                try_files $uri $uri/ /client/index.html;
                }
    location /business {
                alias /data/app/ui/business;
                index index.html index.htm;
                try_files $uri $uri/ /business/index.html;
                }
    location / {
                alias /data/app/ui/common/;
                index index.html index.htm;
                try_files $uri $uri/ /index.html =404;
                }
}

Reference to the orginal solution can be found under following link: reference link

RalfFriedl avatar
us flag
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/543691)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.