nginx how to have a dynamic order of try_files

JoeMoe1984 asked:

I don’t know how better to phrase that question so let me know if there is a better way but here is what I want to do.

I have an app that sends an html file based on the request url which also creates a cache of that html file in a cache folder so that nginx can just serve the cached file the next time someone visits that same url.

This is working as expected except that I don’t want the cache to be read by nginx when there are query parameters. I want the app to be the one to handle the request when this happens but the cache gets sent instead. Here is what I have so far:

    location / {
        root    /path/to/site;
        try_files /content/cache/$uri.html @app;

    location @app {
        proxy_set_header Host $host;

So how do I have the try_files bypass the content/cache/$uri.html and go straight to the @app when there are query args in the url?

My answer:

Someone else will probably think of something complicated involving if but I think I have a very simple solution for this.

Your application caches files using the URL path, without query arguments, as the filename. If the requested URL has a query string, you don’t want to use the cache.

nginx has a variable $is_args which is empty if there is no query string, or contains a ? if there is a query string. You can simply incorporate this:

        try_files /content/cache/$uri.html$is_args @app;

Therefore, if the URL contains a query string, the path that nginx tries will be appended with a ? and will not match the file. The request will then pass to your application.

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.