15

I'd like to divert off requests to a particular sub-directory, to another root location. How? My existing block is:

server {
    listen       80;
    server_name  www.domain.com;

    location / {
        root   /home/me/Documents/site1;
        index  index.html;
    }

    location /petproject {
        root   /home/me/pet-Project/website;
        index  index.html;
        rewrite ^/petproject(.*)$ /$1;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    } }

That is, http://www.domain.com should serve /home/me/Documents/site1/index.html whereas http://www.domain.com/petproject should serve /home/me/pet-Project/website/index.html -- it seems that nginx re-runs all the rules after the replacement, and http://www.domain.com/petproject just serves /home/me/Documents/site1/index.html .

2 Answers 2

32

The configuration has the usual problem that generally happens with nginx. That is, using root directive inside location block.

Try using this configuration instead of your current location blocks:

root /home/me/Documents/site1;
index index.html;

location /petproject {
    alias /home/me/pet-Project/website;
}

This means that the default directory for your website is /home/me/Documents/site1, and for /petproject URI, the content is served from /home/me/pet-Project/website directory.

5
  • 2
    what is the usual problem you refer to and why is alias better? the nginx docs give an example using two roots
    – dcsan
    Jul 11, 2020 at 22:10
  • 4
    The usual problem is that people don't realize how root and location blocks interact. With root directive, nginx appends the path after location block to the root dir to get the full filesystem path to the file. Therefore, if the path specified in location does not exist in the directory specified by root, something unexpected to the user happens. Jul 12, 2020 at 6:45
  • @TeroKilkanen your explanation helped me understand my mistake. THANKS
    – Sandra
    Apr 27, 2023 at 19:05
  • @dcsan The nginx docs examples show roots - one root is for the config file as a whole. The other root directive is for a specific location block - this root overrides the main root directive for that particular location block.
    – ahron
    May 6, 2023 at 6:27
  • Yes, the root inside location overrides the server level root. However, the unintuitive behavior is that nginx appends the URI to the path defined in root directory. May 12, 2023 at 15:47
4

You need the break flag added to the rewrite rule, so that processing stops, and as this is inside a location block processing will continue inside that block:

rewrite ^/petproject/?(.*)$ /$1 break;

Note I also added /? to the matching pattern so that you don't end up with double slashes at the beginning of the url.

1
  • The rewriting isn't needed here at all when alias directive is used like it should be used here. Apr 22, 2015 at 9:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .