Nginx – location specific root

nginx

I'm having a heck of a time getting this (hopefully simple) solution implemented.

We have a site at site.com and served from /home/site/public. We need a specific SUBDIRECTORY of site.com (site.com/gps) to be served from a DIFFERENT document root to avoid security implications. IE site.com/gps should be served from /home/sitegps/public. I have implemented the following location block, but it just results in an http 500 due to infinite redirects. I'm hoping that someone has done this before and knows where I'm going wrong…

# Send all /gps requests to new root
location ~ ^/gps(?:/(.*))?$ {
    alias /home/sitegps/public;
    try_files $uri $uri/ /gps/index.php?$uri&$args;
}

Best Answer

Instead of alias, use can use the root directive inside the location block.

I think you can simplify your location match by just using /gps as well.

location /gps {
    root /home/sitegps/public;
    try_files $uri $uri/ /gps/index.php?$uri&$args;
}

This will not rewrite the request and will expect to match files in a directory called gps like so: /home/sitegps/public/gps/. I wasn't sure if this was required.

Update

Working with the assumption that you do not want to have the gps directory in the /home/sitespg/public directory, I tested out using alias and came up with this config:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html;

    server_name _;

    location / {
            try_files $uri $uri/ =404;
    }

    location /gps/ {
            alias /var/www/gps;
            try_files $uri $uri/ =404;
    }
}

I believe the alias will do what you want but either they regex location match is causing problems or there is something else amiss.

With the trailing slash on /gps/ you will avoid matching paths like /gpsport, but you will need to either rewrite /gps to /gps/ or match /gps exactly with a location block.

rewrite:

rewrite ^/gps$ /gps/

location:

location = /gps {
    alias /var/www/gps;
    try_files $uri $uri/ =404;
}

No doubt there are more variations that will also work.