Why use the try_files directive?

Try_files is useful once a server or location block has matched. So it can be used inside either block.

You may want to:

  • try files and or paths in a particular sequence
  • rewrite the path to match the assumptions required for a particular service.
  • guard against known exploits. Many PHP orientated configuration blocks insist that the file is either an exact match or return a 404 error.
  • jump to another location block using the “named location” (this has uses a @ prefix)

Nginx will try the files in the specified order. It uses the first file found to satisfy the request.

Wrinkles to watch for

Try_files seems a simple directive but can have unexpected side effects.

  • The file is appended to the root. So if, for example, the root is /images and the file is default.gif nginx will try to find /images/default.gif.
  • Try-files operates differently if it is the last statement in the location block.
  • The variable $uri is the URI. That is the part following the domain name and port (if any) from the request.
  • If you use try_files outside a server block and nginx finds a file exists, then it will return this and not proceed to test location paths.

The interplay amongst multiple location blocks with plain text and regular expressions can be subtle.

How to troubleshoot?

Don’t try and get the try_files working until you’ve proven:

  1. The location block matching works properly
  2. The root directory is set correctly and has permissions allowing files to be readable by nginx.
    • If you need to check this it’s easy in a terminal session. Navigate to the root directory and type ls -l at the command prompt. This should show a non-root user. The default is www-data. If it shows root – then permissions need to be set with chown.

Then build up the try_files statement step by step.

  • Get an easy first file working – e.g. a static html file.
  • Then try using substitution for $uri, capture groups or variables.

Insights from others

What directives are typically seen alongside this?




Here’s the official text on the nginx site