Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx reverse proxy 404 on static files

I am looking to reverse proxy one url/path to different ports on an end point that represent different servers hosting their own web apps.

I have the proxy_pass working, but the static files fail because the resources are relative their instance.

I have for example - server_name = myproxy.com:

location /app1/{
    proxy_pass: http://192.168.1.1:8080/;
    proxy_set_header Host 192.168.1.1;
}
location /app2/{
    proxy_pass: http://192.168.1.1:8081/;
    proxy_set_header Host 192.168.1.2;
}
location /{
    proxy_pass: http://192.168.1.1:8080/;
    proxy_set_header Host 192.168.1.1;
}

The reverse-proxy works great as mentioned, except for the static files associated with the app2. App1 static files work fine, but App2 static files result in a 404. Which make sense, because App1 resource files are located at /assets/app1.css this works because I have a redirect for location / in place that resolves back to App1 but App2 resource files, which are totally different /assets/app2.css result in 404.

So, is there a way to rewrite App2 static requests from /assets/app2.css to their respective proxy location? something like:

location /app1/{
    proxy_pass: http://192.168.1.1:8080/;
    proxy_set_header Host 192.168.1.1;
}
location /app2/{
    proxy_pass: http://192.168.1.1:8081/;
    proxy_set_header Host 192.168.1.2;

    *rewrite app2 static urls frome /assets/* to /app2/assets/*
}
location /{
    proxy_pass: http://192.168.1.1:8080/;
    proxy_set_header Host 192.168.1.1;
}
like image 422
abarraford Avatar asked Apr 25 '16 19:04

abarraford


1 Answers

When a file /assets/app1.css(App1) load by rules from location /app1/ then load as /assets/app1.css by rules from location /. App2 has same behavior, but you location / was configurate for App1, not for App2.

Your config must be:

location /app1/ {
    proxy_pass: http://192.168.1.1:8080/app1/;        
}

location /app2/ {
    proxy_pass: http://192.168.1.1:8081/app1/;      
}

Required: The alias app1 should be is same on proxy and upsteam servers. On upsteam server it may been symlink to original webroot application.

Or you can use different subdomain or ports....

server_name app1.localhost;
location / {
    proxy_pass: http://192.168.1.1:8081/;      
}

P.S.

I explored many manipulations with nginx config by proxy. Nginx doesn't work correctly with one rule:

location /app1/ {
    proxy_pass: http://192.168.1.1:8080/;        
}

For example: css and js files will be load - proxy_server/css ... - proxy_server/js ...

from request proxy_server/app1/index.html and you will get 404.

You can add location /css/ rule to config. But your app2 could use this location too. And you can't detect upstream server to proxy by him. You can use reffer to detect upsteam

 server {
    listen          80;

    if ($uri ~ app1/) {
      break;
    }

    if ($http_referer ~ app1/ ) {
      rewrite (.*) /app1/$1 redirect;
    }

    location /app1/ {
        proxy_pass http://192.168.1.1:8080/;
    }
}

but POST data will be destroy after redirect.

It would be great if it was necessary to adjust the configuration only to the proxy server by location. But it's a dream.

like image 171
Evgeniy Tkachenko Avatar answered Sep 22 '22 12:09

Evgeniy Tkachenko