Nginx: Root inside location block

I think I need to improve my reading skills.

Here’s the Nginx pitfalls article.

I can’t seem to understand a simple sentence (bolded) in the following paragraph:

This works. Putting root inside of a location block will work and it’s perfectly valid. What’s wrong is when you start adding location blocks. If you add a root to every location block then a location block that isn’t matched will have no root. Therefore, it is important that a root directive occur prior to your location blocks, which can then override this directive if they need to. Let’s look at a good configuration.

From what I understand, when a request is received by Nginx, after resolving the server block, it will try to match the URI with the location blocks’ location_match (the path to match to). If a URI matches, it will look inside the file location which is defined by root or alias, and serve that file if it is found.

The problem with putting the root inside / location block, instead of putting it in the server block, is that there will be no default root path for all requests. This means that all location blocks will need to have a root or else, it will have no default root path to fall back to and thus the file can’t be found.

Here’s the confusing (to me) sentence again:

If you add a root to every location block then a location block that isn’t matched will have no root.

If the request is for /hello and I only have a location block that only matches exactly to /ola, what does it mean that the location block /ola which is the “location block that is not matched” will have no root?

It is confusing to me because the phrase before that is “If you add a root to every location block ”. How can a location block with a root suddenly loses its root when it is not matched?

Thank you for reading this; I think I’m overthinking this and I get the gist of the message. But yet, it feels that I am misreading the paragraph.

I think the example given in documentation is not great. In it, the / location will catch any non-matching routes, so having no route outside location blocks will probably not make any difference. from digitalocean, I found this explanation:

root /var/www/main;

location / {
    error_page 404 /another/whoops.html;
}

location /another {
    root /var/www;
}

Every request (other than those starting with /another ) will be handled by the first block, which will serve files out of /var/www/main . However, if a file is not found (a 404 status), an internal redirect to /another/whoops.html will occur, leading to a new location search that will eventually land on the second block. This file will be served out of /var/www/another/whoops.html .

Looking further in the nginx documentation:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

The “ / ” request will match configuration A, the “ /index.html ” request will match configuration B, the “ /documents/document.html ” request will match configuration C, the “ /images/1.gif ” request will match configuration D, and the “ /documents/1.jpg ” request will match configuration E.

If a location block for a request doesn’t exist and there is no root outside , there is no default location to send the request. Even if it results in an error, it should at least point to a valid folder where the request can be processed and the error handled.

At least that’s what I think. I could be wrong.

1 Like

This is my exact understanding as well.

I guess I’m perplexed by the difference in my understanding and what the sentence implies.

If I were to rewrite it to reflect my understanding:

If you add a root to every location block (and do not add a root in the server block) then (in the event that) a location block that isn’t matched (, the request) will have no root.