Understanding location blocks and try files

Francis Daly francis at daoine.org
Fri Jan 24 01:41:44 UTC 2014

On Thu, Jan 23, 2014 at 06:55:04AM -0500, AD7six wrote:

Hi there,

> Allow me to rephrase: Is there a way to define rules for static files -
> without that causing problems for dynamic requests matching the same url
> pattern?

Asking the question that way, the answer is probably "no".

Whatever rules you write are based on url patterns (prefix or
regex). nginx does not know whether files are involved until you tell
it to look.

If you want a completely generic (= arbitrary) uri/file layout, you
probably won't find an nginx config you can drop in and have Just Work.

> Nginx docs are full of warnings about If is evil and advocates using
> try_files instead - yet doing that is not functionally/logically equivalent,
> which leaves me kind of stuck.

"If is evil" inside a location.

You tested try_files outside a location.

That might make a difference.

> I did also try using the front controller as a 404 handler which worked
> exactly how I am trying to get things to work _except_ of course everything
> from the front controller is a http 404.

Why "of course"?


Might the suggestions in and around


offer a hint to what might work for you?

> One of the goals
> of asking here was to eventually achieve a "just include this config file"
> solution to optimize frontend performance. This post so far leads to the
> conclusion that's not possible and an application-specific config file is
> required for all apps.

I suspect that that's pretty much required, based on the idea that
generic = slow, specific = fast; and nginx being built to be fast.

Also "optimize" can mean different things, depending on what specifically
is to be improved at the expense of what else.

> An example of the kind of apache rule I'd like to emulate with nginx is:
>     <FilesMatch "\.(eot|otf|ttc|ttf|woff)$">
>         Header set Access-Control-Allow-Origin "*"
>     </FilesMatch>

nginx does not have any equivalent to apache FilesMatch, which is
approximately "when any filename which matches this pattern is served,
apply this configuration as well".

You may be able to get close, using nginx configuration. But it may not
be close enough for you to be happy with.

> The suggestion there is to include the following:
>     # Cache static files for as long as possible
>     location ~*
> .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$
> {
>         expires max; log_not_found off; access_log off;
>     }
> Which would mean any request for those file types which is intended to be
> handled by wordpress - fails.

That configuration says "all requests that match these patterns (apart
from those that match a different location) are files to be served from
the filesystem".

If you have a request that matches this location that is *not* a file
to be served from the filesystem, that configuration is not the one you
want to use.

(Use, for example, "location ^~ /wordpress/" and a request for
/wordpress/one.ogg will not match the regex location above.)

(Or use "error_page 404" to decide what to do about "file" requests
which are missing.)

> it also means you can't optimize static requests _and_ do "funky caching" or
> similar by which I mean handling the first request for something that
> doesn't exist, and caching the result in a path such that the next and all
> subsequent requests are served by the webserver:

fastcgi_cache? Or try_files?

I suspect I'm missing something obvious, but why can't you do this? If
you want the effect of "expires max", why do you care whether you are
serving from file, from cache, or from php directly?

Only if it matters: could you describe how you want nginx to handle
different requests, and how it should know to do what you want?


Francis Daly        francis at daoine.org

More information about the nginx mailing list