Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I am converting a legacy Apache server to Nginx and do not have the luxury of changing URL's or rearranging the filesystem.

Is it possible to use nested location{} blocks in the Nginx configuration to tell it to feed the .php files in an aliased directory to fastcgi while serving static content normally?

Similar configuration to what fails me:

server {
  listen 80;

  location / {
    index  index.html;
  }

  location /foosite/ {
    alias  /var/aliases/foo;
    location ~ \.php$ {
      include fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
  }
}

Requests for /foosite/static.jpg are served fine, but nginx appears to garble the path to any .php files when attempting to dispatch them to fastcgi.

share|improve this question

3 Answers 3

up vote 4 down vote accepted

The solution provided here is not a solution. And it's not correct anymore. Using Lucid (10.4) I was able to use this solution. The problem with womble's solution is that it doesn't set the DOCUMENT_ROOT parameter properly; rather, it includes the script name in the document_root.

This seems to work OK.

location /foosite {
    alias /home/foosite/www/;
    index index.php index.html index.htm;

    location ~ /foosite/(.*\.php)$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$1;
        include /etc/nginx/fastcgi_params;            
    }                                                 
}

Using nginx/0.7.65

share|improve this answer
    
Thanks. I'm not having this problem any more, but I am in the middle of a new deployment this week so I'l give it a whirl just to confirm ;) –  allaryin May 24 '12 at 15:59

The "garbling" you talk about is, as far as I can tell, a bug in nginx relating to nested location blocks (or maybe aliases in location blocks that do regex-based matching without a capture... I'm not sure). What I was able to do, however, was fairly straightforward.
First, you can put all your fastcgi parameters, including the fastcgi_pass line and fastcgi_param SCRIPT_FILENAME $request_filename into a separate file for inclusion in the relevant parts of the site. I put mine in /etc/nginx/fragments/php.

Then, for /foosite, you need two location blocks, like so:

location /foosite {
    alias /var/aliases/foo;
}

location /foosite(.*\.php)$ {
    alias /var/aliases/foo$1;
    include /etc/nginx/fragments/php;
}

One thing to be wary of here -- unlike "regular" location blocks, it appears that regex-based matching runs in the order specified in the config file (not longest-match-first, as appears to be the case for non-regex location blocks). So, if you're doing a site-specific PHP location, as well as a generic "all-site" PHP handler (location ~ \.php$) then you'll need to put the generic "all-site" handler last in the server block, or all hell will break loose.

Yeah, this sucks, and if I get the motivation up I might try and work out exactly what's going wrong with the nested case (the config parser doesn't barf on it, so I suspect it's supposed to work but nobody actually uses it, so it's buggy).

share|improve this answer

AFAIK, you cannot use nested blocks.

Try something like the following instead.

location / {
  root /var/www;
  access_log off;

  index index.php index.html;
  expires 1d;

  try_files $uri $uri/ /index.php?q=$uri;
}

location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_buffer_size 128k;
  fastcgi_buffers 4 256k;
  fastcgi_param  SCRIPT_FILENAME  /var/www$fastcgi_script_name;
  include        /usr/local/nginx/conf/fastcgi_params;
}

You can modify the second block to be something like

location ~ /foosite/.*php$

(needs testing)

share|improve this answer
    
That's what I was afraid of. –  allaryin May 30 '09 at 0:30

Your Answer

 
discard

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.