try_files seemingly looking in wrong directory
I am trying to set up try_files, but am running into an issue: It seems the fallback "empty.png" file is not picked up, even though it is located at /path/to/old_cache_data/empty.png
. The files that actually exist (i.e. no fallback) are found without problems. Also interesting enough I am not getting an nginx 404, but the 404 page from the app that is handled by the proxy_pass below.
Stuff I tried so far:
- Removing the leading slash, which lead to this curious error:
open() "/usr//htmlempty.png" failed (2: No such file or directory)
, Seems weird to me as /usr/html is not specified anywhere as any sort of fallback path. - Specifying an absolute path (i.e.
try_files $uri /path/to/old_cache_data/empty.png;
)
Relevant rules:
# legacy static cache
location /cache/ {
root /path/to/old_cache_data;
try_files $uri /empty.png;
}
# pass-through
location / {
[bunch of proxy-settings]
proxy_pass [the target url];
}
So, not sure where exactly I'm "holding it wrong". It seems like try_files
does not pick up on the root
in the location but somehow does a weird fallback.
EDIT: I found out that placing the empty.png in the "cache" sub-folder and changing the try_files to try_files $uri /cache/empty.png;
actually works. I do not understand why this is the case though.
Solution 1:
As it stated by the documentation, last parameter of the try_files
directive can be
- a new URI;
- HTTP error code:
=code
; - named location ID:
@location_name
.
You are using /empty.png
which is treated as a new URI that does not fall under the location /cache { ... }
thus being served by the location / { ... }
. When you remove the leading slash you get the new URI empty.png
that does not fall under any of your locations including location / { ... }
. Every server
block have some default root path prefix/html
where prefix is specified at the compilation time and can be checked with the nginx -V
command (looks like yours is /usr/
). So as being said by the root
directive documentation,
A path to the file is constructed by merely adding a URI to the value of the
root
directive.
which gives us prefix /usr/
+ default root /html
+ URI empty.png
= /usr//htmlempty.png
.
When you change last try_files
parameter to the /cache/empty.png
, this URI is served with the same location /cache { ... }
block with the file /path/to/old_cache_data
+ /cache/empty.png
= /path/to/old_cache_data/cache/empty.png
. And if you understand all the above information correctly, you should notice that with your configuration you can't access any files in the /path/to/old_cache_data
folder except those in the /path/to/old_cache_data/cache
subfolder. Check the difference between root
and alias
directives for better understanding.