I'm trying to write an Nginx config with the following semantics, expressed in hopefully-readable psuedo-config:

location /dir1/ /dir2/ {
  if (matches a .php file) {
    serve with php
  } else if (matches a non-.php file) {
    serve as static content
  } else {
} else {
  serve with /index.php

How do I do this? I have a decent sense of Apache configuration, but I don't have a good enough grasp on Nginx to sort out the semantics of try_files and location matching and internal redirects and stuff. Any tips on how I should structure this?

For reference, the mod_rewrite-based configuration I'm currently using with Apache is

# Any URL not corresponding to a directory gets rewritten to index.php
RewriteCond $1 !^dir1/
RewriteCond $1 !^dir2/
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]

# Allow access to files in any of the directories
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ - [L]

# If either step above resulted in a php file, process it
<FilesMatch "\.php$">
    SetHandler application/x-httpd-php

2 Answers 2


You could simplify this (NGINX is all about being simple) by using the try_files directive. This allows you to cascade scenarios in one statement.

In your case since you want to redirect any directory call to index.php, you can have it try the specific file first, and then index.php:

  try_files $uri index.php;

Also I would adjust your location detection for php:

  location ~ ^(.+\.php)(.*)$ {

     [your fastcgi block here]


Doing this, you don't need a "location /" entry. Your complete config for this site would be something like this (I am using php-fpm, your php location may vary):

server {

     server_name www.example.com;
     root /path/to/docroot;

     access_log /path/to/logfile;
     error_log /path/to/errorlog;

     index index.php;

     try_files $uri index.php;

     location ~ ^(.+\.php)(.*)$ {

            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_buffers 8 16k; 
            fastcgi_buffer_size 32k;                                         
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;   
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;                    


  • How do I extend that to handle restricting static files to /{dir1,dir2} and restricting php to /{dir1,dir2}/ and index.php? I think it's the last part I'm having particular trouble with. I guess I could do it with two php/fastcgi blocks, but that seems suboptimal.
    – jon
    May 19, 2012 at 16:25
  • Oh sorry I misread your question then. You wouldn't need separate php blocks but you would have to break out each location including the root: location ^ /dir1/ { try_files $uri /index.php; } location ^ /dir2/ { try_files $uri /index.php; } location / { error_page 404 /index.php; try_files index.php; }
    – Brian P
    May 19, 2012 at 18:20
  • @BrianP Welcome to ServerFault and thanks for the answer. You should rather edit your answer so that it fully answers the question instead of continuing it in a comment, so that future readers can easily find the solution.
    – mgorven
    May 19, 2012 at 19:08

It's better to get a basic understanding of how nginx works before writing a config for it. Read howtos and examples from http://wiki.nginx.org/Configuration

Nginx config is not about if-then-else. There's distinct stages of processing each request, and you just define what are parameters of each stage.

You can make use of this template:

location ~ \.php$ {
  fastcgi_pass    unix:/var/run/php/fcgi;
  fastcgi_index   index.php;
  fastcgi_param  SCRIPT_FILENAME  /var/www/localhost/htdocs$fastcgi_script_name;
  include /etc/nginx/fastcgi_params;

location / {
   root /some/folder;
   error_page 404 /index.php
  • I've read most of the pages linked to in the first two sections of that page, the reference documentation for both CoreModule and HttpCoreModule, and a number of other s-f questions. I think I could translate the psuedo-config (if-then-elses) in my question to nginx trivially by using if, but IfIsEvil advises against it; hence my question. If you could point me to definitive documentation on what Nginx's processing stages are, I'd be much obliged.
    – jon
    May 19, 2012 at 6:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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