7
votes

Having a hard time trying to figure out location blocks in the nginx config. This is what I have:

server {
    listen          80;
    server_name     _;

    access_log      /var/log/nginx/example.com.access_log;
    error_log       /var/log/nginx/example.com.error_log warn;

    root                /var/www/root;
    index               index.php index.htm index.html;
    fastcgi_index       index.php;

    location /wp/ {
        root                /var/www/wordpress;
        index               index.php index.htm index.html;
        fastcgi_index       index.php;
    }

    location ~* \.php$ {
        try_files            $uri =404;
        keepalive_timeout    0;
        fastcgi_param        SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass         127.0.0.1:9000;
    }
}

Browsing to / works as expected and shows the website in /var/www/root, but if locations work as I think they should browsing to /wp should take me to the wordpress installation in /var/www/wordpress. All I am getting is:

404 Not Found

nginx/0.7.67

If I relocate the /var/www/wordpress directory to /var/www/root/wordpress and browse to /wordpress all is perfect.

What am I doing wrong with the location block??

I've never configured nginx before and am a bit of a complete web newb anyway.

I want to be able to have more location blocks for other applications as well. This is really just a basic example for posting on here.

Updated nginx to version in Debian Squeeze backports. No improvement:

404 Not Found

nginx/1.1.19

1
Have you tried going to /wp/ instead?Nikhil Baliga
You don't want to imagine how out of date nginx/0.7.67 is.Dayo
I've tried /wp/ as well. This is the nginx from the Debian 6 repositories. I guess Debian does tend to get a little behind. I tend to prefer to stick with what's in the repos though.goji
You can get up-to-date versions for Squeeze from the backports repo.Moritz Bunkus
I'll try update and post back.goji

1 Answers

7
votes

The reason why it is not working is that ...

At the server level, you have "root /var/www/root". So basically, every location block will use this unless specifically overridden. This is good practice.

You have then overridden it in the "wp" location block to "/var/www/wordpress". However, the php location block is still using the default.

Now when you put in a request to "/wp/folder_a/file_a.php" which is physically located at "/var/www/wordpress/folder_a/file_a.php", the request hits the php location block and given the root folder active for that block goes to look for the file in "/var/www/root/folder_a/file_a.php". As a result, you get a "404 not found".

You can change the server level root directive to "/var/www/wordpress" and remove the override in the wp location. This will solve that problem but php scripts under "/var/www/root" will no longer work. Not sure if you have any.

If you need to run php under both "/var/www/root" and "/var/www/wordpress", you need to do this:

server {
    ...
    root                /var/www/root;
    index              index.php index.htm index.html;
    # Keep fastcgi directives together under location
    # so removed fastcgi_index

    # Put keepalive_timeout under 'http' section if possible

    location /wp/ {
        root                /var/www/wordpress;
        # One appearance of 'index' under server block is sufficient
        location ~* \.php$ {
            try_files           $uri =404;
            fastcgi_index      index.php;
            fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass         127.0.0.1:9000;
        }
    }

    location ~* \.php$ {
        try_files           $uri =404;
        fastcgi_index      index.php;
        fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass         127.0.0.1:9000;
    }
}

That is, nest a duplicate php location block under the wp location block. It will inherit the root directive for wp.

To help keep things succint and ease edits etc, you can put the fastcgi directives into a separate file and include it in as needed.

So in /path/fastcgi.params, you have:

    fastcgi_index      index.php;
    fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass         127.0.0.1:9000;

Your conf can then be:

server {
    ...
    root                /var/www/root;
    ...
    location /wp/ {
        root                /var/www/wordpress;
        location ~* \.php$ {
            try_files           $uri =404;
            include /path/fastcgi.params;
        }
    }

    location ~* \.php$ {
        try_files           $uri =404;
        include /path/fastcgi.params;
    }
}

In this way, if you need to edit any fastcgi param, you just edit it in the one place.

PS. Updating your nginx will not solve this as it is not a version issue .. but update anyway!