NGINX Reverse proxy not loading resources

I'm trying to put a reverse proxy in front of a few internal web services.

Nginx is setup and working properly to serve request. If I only serve one location / in my conf file, it loads that proxy_pass target successfully ie:

location / {
  proxy_pass https://internal.ip:port/;
 }

Browsing to the https://public_proxy_address/ loads that internal resource perfectly.

However, since I have multiple internal applications, I want to proxy all of them through nginx. So, in my testing I have changed the conf to as follows:

location /app1 {
  proxy_pass https://internal.ip:port/;
}

With this in place, I get the main/default internal app index page, but the view source shows me that no link stylesheets, js, or other resources are being re-written. Therefore the entire contents of the page, fails to load. In Apache, I would probably write a proxyhtmlurlmap ^/resource/ /app1/resource R. I cannot find any way to achieve this in nginx though.

I have also tried this, to no avail:

location /app1 {
  rewrite /resource(.*?) /app1/resource$1 break;
  proxy_pass https://internal.ip:port/;
 }

How do I get nginx to properly prepend the target location (app1) to the requested resource urls so that they load?


As I don't have enough credit, I cannot comment on entries, so, here comes my response as a separate entry.

I don't know why the OP disagrees but I think Martin Fjordval identifies the problem correctly and suggests the right thing. I'd suggest a slight modification to his snippet as below though;

                location /app1/ {
                    proxy_set_header Host $http_host/app1;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Scheme $scheme;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_redirect    off;
                    add_header Pragma "no-cache";
                    add_header Cache-Control "no-cache";

                    proxy_pass http://internal.ip:port/;
                    sub_filter 'action="/'  'action="/app1/';
                    sub_filter 'href="/'  'href="/app1/';
                    sub_filter 'src="/'  'src="/app1/';
                    sub_filter_once off;
            }

So, if you are sure that all your relative urls that are starting with '/' needs redirecting, the above would append '/app1/' to them all and get them caught by the 'location /app1/' block when referenced. You can then view the page source and confirm that the rewriting is happening.

You'd also probably need the whole or at least the part of the 'proxy_set_header' shabang, especially the 'proxy_set_header Host $http_host/app1' bit.


If I understand your problem correctly it sounds like the problem is your application thinks it's hosted at the root uri / while it's actually hosted at /app1 and just not being told this. Nginx will not normally modify the response of your backends which is what you're expecting, however, it is possible.

First you want to check if there's a configuration option in your app where you can define the root uri. If there is then setting that is by far the easiest solution.

If you cannot find anything you can use the substitution module to replace the urls in the HTML. Do note that in order for this to work you need to disable GZIP encoding on the backend so nginx can see the uncompressed HTML.

An example of what your subfilter might look like

location /app1 {
    sub_filter '<a href="/resource/' '<a href="/app1/resource/';
    sub_filter_once off;

    proxy_pass https://internal.ip:port/;
}