nginx reverse proxy multiple locations

I want to make a reverse proxy for multiple applications.
Something like this:

https://proxyip/app1 -> https://10.10.0.1/
https://proxyip/app2 -> https://10.10.0.2/
etc.

Currently, my config is:

server {
    listen 443 ssl;
    server_name _;

    ssl_certificate     /etc/nginx/cert.crt;
    ssl_certificate_key /etc/nginx/cert.key;

    proxy_set_header    X-Real-IP               $remote_addr;
    proxy_set_header    Host                    $host;
    proxy_set_header    X-Forwarded-For         $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto       $scheme;

    client_max_body_size 0;

    error_log   syslog:server=unix:/dev/log;
    access_log  syslog:server=unix:/dev/log;

    location /app1/ {
        proxy_pass https://10.10.0.1/;
    }

    location /app2/ {
        proxy_pass https://10.10.0.2/;
    }

    location ~ /\. {
        deny all;
    }
}

But nothing works.
When I go to https://proxyip/app1 it redirects me to https://proxyip/Account/login and I'm getting 404. It should go to https://proxyip/app1/Account/login. Here is logs:

Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /app1/ HTTP/1.1" 302 0 "-" "BrowserUserAgent"
Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /Account/Login?ReturnUrl=%2F HTTP/1.1" 404 571 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /app1/ HTTP/1.1" 302 0 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /Account/Login?ReturnUrl=%2F HTTP/1.1" 404 571 "-" "BrowserUserAgent"

When I'm removing trailing / from proxy_pass, I'm getting 404 from application itself.
Logs:

Jun 06 15:21:42 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:42 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /app1/ HTTP/1.1" 404 1831 "-" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /Content/bundleCss HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /Content/themes/base/jquery HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"

Can you help me?

to @Tero-Kilkanen:
I've tried as you said:

location ~^/app1(.*)$ {
proxy_pass https://10.10.0.1$1;
}

But still nothing. Here is logs:

Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /app1 HTTP/1.1" 404 1831 "-" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /Content/bundleCss HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/modernizr HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /Content/themes/base/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"

Application IIS logs on error:

2017-06-08 12:41:27.264 /Error/NotFound - "E:\wwwroot\MyAppPool\Error\NotFound" 404 "app-server" - 0 2105 587
2017-06-08 12:41:27.264 /app1 - "E:\wwwroot\MyAppPool\app1" 404 "app-server" - 0 2105 587

Application IIS logs when connecting sucessfully (without proxy):

2017-06-09 06:46:36.934 / - "E:\wwwroot\MyAppPool" 302 "app-server" - 0 267 612
2017-06-09 06:46:44.673 /Account/Login ReturnUrl=%2F "E:\wwwroot\MyAppPool\Account\Login" 200 "app-server" - 0 17530 743
2017-06-09 06:46:44.878 /bundles/modernizr v=inCVuEFe6J4Q07A0AcRsbJic_UE5MwpRMNGcOtk94TE1 "E:\wwwroot\MyAppPool\bundles\modernizr" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 11477 634
2017-06-09 06:46:44.892 /bundles/jquery v=Z_3sx_Om2qdGQNW4A5Csgy0WZLaXSa4Eg8ukUl26_Qw1 "E:\wwwroot\MyAppPool\bundles\jquery" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 96542 631
2017-06-09 06:46:44.905 /Scripts/app/signatureHelper.js - "E:\wwwroot\MyAppPool\Scripts\app\signatureHelper.js" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 10309 600
2017-06-09 06:46:44.920 /bundles/bootstrap v=H2j5HUSj46jlSq1Se76I-uTAYq6y_MryNeOkhmo3adE1 "E:\wwwroot\MyAppPool\bundles\bootstrap" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 40031 634
2017-06-09 06:46:45.234 /Content/bundleCss v=QR3LEdUKMTwhOusb6Ic-dRnsOi-C89Qfl8hxv_73Pr41 "E:\wwwroot\MyAppPool\Content\bundleCss" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 679954 649
2017-06-09 06:46:45.417 /Content/themes/base/jquery v=GZKJzOOlsTUy2AD4HAw4TdqockAuF9srZRUOXVJLoJQ1 "E:\wwwroot\MyAppPool\Content\themes\base\jquery" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 45215 658
2017-06-09 06:46:45.456 /bundles/extlibs v=4Ziz4fY8b9xGa5ThFN7ipb8OedxUWcMRvcf0slVL57E1 "E:\wwwroot\MyAppPool\bundles\extlibs" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 6293867 632
2017-06-09 06:46:46.451 /fonts/glyphicons-halflings-regular.woff - "E:\wwwroot\MyAppPool\fonts\glyphicons-halflings-regular.woff" 200 "app-server" "https://10.10.0.1/Content/bundleCss?v=QR3LEdUKMTwhOusb6Ic-dRnsOi-C89Qfl8hxv_73Pr41" 0 23690 676

Solution 1:

nginx proxy_pass documentation states that when proxy_pass is specified with an URI, then the proxy_pass destination is used and the path in location is not used.

Example:

location /app1 {
    proxy_pass http://proxy.example.com/app1;
}

With this configuration, all requests that begin with http://example.com/app1 will end up to http://proxy.example.com/app1. This includes http://example.com/app1/dir1.

The solution to fix this is to use regular expression capture in the location directive, and use the captured variable in proxy_pass destination, like this:

location ~ ^/app1(.*)$ {
    proxy_pass http://proxy.example.com$1;
}

This will make nginx append the string after app1 to the proxy_pass destination line.

Solution 2:

Your setup should work without the last slash / in proxy_pass directive.

One thing that you need to consider is that when the proxy traffic is passed the location path will be passed as well, meaning when someone requests:

https://proxyip/app1, nginx will request the following url from the backend: https://10.10.0.1/app1

Which will result in:

https://proxyip/app1  => https://10.10.0.1/app1 
https://proxyip/app2  => https://10.10.0.2/app2

The solution here will be:

  1. Create custom rewirte configuration on your backend server where you will rewrite appX to /
  2. Move your app into the corresponding sub folder for the specific location of the backend server.