Nginx try_files won't trigger response from index.php

Christiaan picture Christiaan · Oct 10, 2012 · Viewed 8k times · Source

I'm having a problem with try_files not appearing to pass off requests for non-existent files to the last specified value, in my case index.php. I'm using Wordpress and the XML Sitemap generator plugin I use creates virtual XML files and a virtual robots.txt that's handled by Wordpress. Unfortunately try_files doesn't seem to be passing the requests for these files to Wordpress.

Here's my server configuration:

server {
        ## Web domain
        server_name christiaanconover.com;
        ## Site root
        root /var/www/christiaanconover.com;
        ## Index
        index index.php index.htm;

        ## Common Wordpress configuration
        include wp.conf;

        ## Include PHP configuration
        include php.conf;

        ## Gzip Compression
        include gzip.conf;

        ## Include W3TC configuration
        include /var/www/w3tc/christiaanconover.com;
}

I run multiple separate Wordpress sites on this server, so to save time I created a file wp.conf that contains all the commonly used configuration elements for Wordpress. Here is the contents of wp.conf:

location / {
        ## Prevent PHP files from being served as static assets, and fall back to index.php if file does not exist
        try_files $uri $uri/ /index.php?$args;

        ## If a file exists, serve it directly
        if (-f $request_filename) {
                break;
        }

        ## Wordpress Rewrite
        if (!-e $request_filename) {
                rewrite ^ /index.php last;
        }
}

Everything else is working perfectly, but the try_files arrangement just doesn't seem to hand off properly. Any ideas?

Answer

cobaco picture cobaco · Oct 10, 2012

you're running into one of the problems described at http://wiki.nginx.org/IfIsEvil#Examples

the ifs you specified in the wp.conf are uneeded you already have them covered with your try_files, so you can just remove them, yielding:

location / {try_files $uri $uri/ /index.php$is_args$args;}

that will:

  1. check if a file matching $uri (relative to the location specified by the root directive) exists
  2. if not check if directory match exists
  3. else redirect to /index.php$is_args$args

Where $is_args evaluates to ? when $args is set.