What does try_files do in Nginx’s Config

Taylor Built Solutions Logo

Recently I setup a new WordPress instance on Linode that I planned to copy a backup of this blog to. The instance was easy to setup and UpdraftPlus made it easy to import the backup. Normal issues with restoring a back up to a new instance such as making sure the domain of the site is correct were fixed with ease. So what was the problem?

When viewing the blog to make sure everything worked as normal the front page with a list of posts loaded fine but the posts themselves returned 404 Not Found. This was confusing because the content of the posts were available from the admin panel. I could edit them and see all their details but not load them as a user would.

What, pray tell, does this have to do with nginx and try_files? In this particular case the WordPress image used to create the WordPress “Quick DeployApp” uses nginx and set the try_files fall back code to 404.

So what does try_files actually do?

In short try_files is a way for nginx to look for files (in this case posts) under a specified location in an nginx server. If the file that is being requested can’t be found try_files can specify a page to return. It can also specify a code to be returned. The nginx server setup was created in the quick deploy app looked as follows:

location / {
    try_files $uri $uri/ /index.php?$args =404;
}Code language: Nginx (nginx)

What did I do to fix the situation?

My initial suspicion from reading the first part of the try_files documentation was to assume that the code at the end was the reason I was getting the 404 Not Found when trying to view posts. Changing the configuration as follows allows the posts to be viewed:

location / {
    try_files $uri $uri/ /index.php?$args ;
}Code language: Nginx (nginx)

But why does this work?

There is a great breakdown of how try_files works on the Get Page Speed blog. I’ll summarize the details of this specific problem here. The $uri and $uri/ arguments to try_files look for the requested URI as a file/page then a directory respectively. WordPress, however, stores the posts in its database and needs index.php to be used with the requested post (contained in $args in this case) to be able to return the desired post.

This explains why my the updated configuration works but not why having the code as the fallback option returns the fallback instead of going through index.php. The nearest explanation that I have seen so far is the possibility that the configuration rules for php files isn’t setup to forward requests to php-fpm correctly. Given that I am not an expert on how to setup nginx and WordPress I need to test this before claiming that it is the answer.

Conclusion

While I am not completely sure why the posts weren’t returned by the /index.php?$args section of the try_files statement and 404 was returned I can be relatively confident that the fix works. The posts are viewable now. Trying to enter a post name that doesn’t exist causes the WordPress processor to return a page not found screen. This is better than returning a 404 Not Found in my opinion.

If you know why the fallback was returned in the initial configuration I would love to hear from you!

Leave a Reply

Your email address will not be published. Required fields are marked *