Nginx – Reverse Proxy – Remove Subdirectory

nginx

In the near future I'm going to have 3 nginx servers. One is a reverse proxy for SSL for the two others. So, for example, I go to:

https://www.mysitename.com/site1

The two other servers in this example are site1 and site2. I installed the SSL certificate on the proxy and I want to use a reverse proxy (SSL not required since all 3 are on an internal network).For testing purposes I'm having nginx listen on 443 for SSL/reverse-proxy, listen on port 8081 which is a rails app for site1, and 8082 is for site2.

I have this…

server {
    listen                  443;
    server_name             mysitename.com;

    ssl                     on;
    ssl_certificate         ssl/mysitename.com.crt;
    ssl_certificate_key     ssl/mysitename.com.key;
    keepalive_timeout       60;

    location /site1 {
        proxy_pass http://localhost:8081;
        proxy_set_header    Host            $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect http:// https://;
    }

    location /site2 {
        proxy_pass http://localhost:8082;
        proxy_set_header    Host            $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect http:// https://;
    }
}

So when I visit www.mysitename.com/site1 I want it to basically return what would normally come from localhost:8081 (or later down the line an internal IP for another server).

Is there a way to have it strip the "site1" from the localhost call? What it seems to be doing is using localhost:8081/site1. The site1 and site2 sites are of the nature "/login/index" or "/whatever/list", etc, with no "site1".

There are also redirects in the site controllers (using redirect_to) that go from things like /login/index to /whatever/list.

Am I going to have to redesign the URL's of the site to use site1? Or can the NGINX proxy figure it out?

Thanks.

Best Answer

Quoting http://nginx.org/r/proxy_pass:

If proxy_pass is specified with URI, when passing a request to the server, part of a normalized request URI matching the location is replaced by a URI specified in the directive:

location /name/ {
    proxy_pass http://127.0.0.1/remote/;
}

That is, you have to use proxy_pass like this:

location /site1/ {
    proxy_pass http://localhost:8081/;
    ...
}

Note the trailing / in the proxy_pass directive - it will replace part of the original URI matched by the location, i.e. /site1/.