Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

i had a project in which i had to redirect all not found files to the index.php. I did this in apache with placing a .htaccess file in my project folder. the file's contents are--

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

now i wanted the same in nginx. here is how my nginx.conf looks like

root   /usr/local/apache2/htdocs;
index  index.php index.html index.htm;
location /project/ {
            root   /usr/local/apache2/htdocs;
            index  index.php index.html index.htm;
            try_files $uri $uri/ index.php;

now whenever i make a request like http://localhost/project/hello then this request should go to http://localhost/project/index.php but this says File not found.

Now why i thought this would work is because since the root directive inside the location block overrides the root directive outside the block (though there values are same), the rewrite module would look for /usr/local/apache2/htdocs/project/index.php. What am i missing here?


This configuration works

root   /usr/local/apache2/htdocs;
location /project/ {
            index  index.php index.html index.htm;    #effectively root here is /usr/local/apache2/htdocs
            try_files $uri $uri/ /project/index.php;

But i dont see why this should work because as pointed out in the docs here directory matched in the location block is appended to the value of root directive

share|improve this question
I'm confused now... are you confused about the index directive or the try_files directive? The index directive refers only to a filename, not a directory path. Thus, if your URI references a directory within the location directive path, those files will be checked relative to that directory. try_files uses a full path / URI. – Jeff Ferland Mar 9 '12 at 16:24
up vote 5 down vote accepted
 location /project/ {
             root   /usr/local/apache2/htdocs;
             index  index.php index.html index.htm;
-            try_files $uri $uri/ index.php;
+            try_files $uri $uri/ /project/index.php;

Perhaps you needed to specify the root in the URL? Otherwise, there is no reference point for the URL. The server can't guess at whatever directory it was last in or the user intended. If that doesn't accomplish what you want, comment back and I'll spin up a server to do a quick test on.

share|improve this answer
this time it works. but i dont get this. the /project/ from location block is appended to the root directive's value as mentioned by the docs here – lovesh Mar 9 '12 at 16:05
@lovesh You're confusing prepending the root with prepending the location. /usr/local/apache2/htdocs is defined as where we start looking for the files, but if the URI doesn't include /project/, we won't reach this block. You have to specify /project/ because the location directive is not prepended. If it were, you would never be able to redirect outside of this subdirectory. – Jeff Ferland Mar 9 '12 at 16:14
alright i get it. When it looks for the file say xyz.php it will look in root+location but when it rewrites it uses the root+rewrite_path (+ means concatenation) – lovesh Mar 9 '12 at 16:27
@lovesh No, it looks in root+uri. Root is defined by the URI. consider if you had another block like location /project2/ { root /tmp; }. Your rewrite path defines a new URI. Now imagine what happens if I declare /project2/index.php in the block from my answer. The server bases the root off that URI. The location directory still needs to exist in the root directory. – Jeff Ferland Mar 9 '12 at 16:33

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.