Home > Net >  NGINX: Proxy only upstream calls
NGINX: Proxy only upstream calls

Time:06-18

I hope this question is not too simple to include here. Any advice would be appreciated.

I have a situation where I am using a single url to host multiple different angular projects on nginx. I use path extensions to differentiate between the sites. It looks something like this:

server {

listen 443 http2 ssl;
#listen       [::]:80;
server_name  site.local;

. . .

root         /usr/share/nginx/html/. . .;

. . .

    location /site1 {
        alias  /usr/share/nginx/html/. . .;

. . .

    location /site2 {
        alias  /usr/share/nginx/html/ . . .;

. . .

What complicates this is that site1 and site2 share an upstream api on tomcat. When these api calls are made, however, "site1" or "site2" gets inserted into the call.

I'm quite ignorant as to how proxying works on nginx, so attempting to use a proxy_path in the location blocks in the simplest way results in calls to nginx (for html files etc.) are also proxied, making the site inaccessible.

Is there a way to set it up such that only upstream calls get rewrote/proxied?

Any advice would be greatly appreciated.

CodePudding user response:

I'm going to make a few assumptions about your build and correct me if I am wrong. but I see two options to resolve this considering they share the same API you can make the changes in the angular build Or in NGINX. Assuming your nginx server name is example.com it contains a location for /site1 and /site2

example.com/site1
example.com/site2

Options 1 Angular

if the URL is public you can simply route calls by setting the environment.ts inside the environments folder.

export const environment = {
  production: false,
  apiUrl: 'https://example.com/api',
}

You may need to deploy a production environment.ts and a test environment.ts with their respective apiUrl's for each build. But assuming they share the same API all you would need is a nginx location to said upstream API

location /api/ {                                 
proxy_pass  upstream_api;
}    

Option 2 NGINX

Let's assume you don't want the full API URL in the environment.ts what is the Nginx option. I don't like this method because it's not as D.R.Y and you find yourself writing two nested locations.

 location /site1 {
        alias  /usr/share/nginx/html/. . .;
    #any other settings...
        #SUB LOCATION TO API
        location /site1/api/ {
            rewrite /site1/(.*) /$1  break;
            proxy_pass  upstream_api;
            #any other settings...
        }
    }


location /site2 {
        alias  /usr/share/nginx/html/. . .;
    #any other settings...
        #SUB LOCATION TO API
        location /site2/api/ {
            rewrite /site2/(.*) /$1  break;
            proxy_pass  upstream_api;
            #any other settings...
        }
    }

Let's break this down. the first location /site1 will qualify and url using site1 thus your SPA application can route to any url. But when making a request to an API it will seek the 2nd qualifier in the nested location /site1/api/ we use /site1/api so that Nginx knows that /api is not outside of the location. Lastly rewrite /site1/(.*) /$1 break; will remove the site1 and send the rest of the url upstream to resolve your problem. Hope this helps.

  • Related