Issue w/ nginx in hybrid static/php load balancer scenario

I have nginx set up as a load balancer in front of two machines
running fastcgi/php, and nginx for static content. The desired goal is
to have all php pages (including the site index pages of .*/index.php)
processed by the fastcgi/php upstream, and everything else provided by
the static servers. The following is what I have and what I believe
should have worked, but it appears to run all directory paths via the
static rule, rather than the php rule which matches the index.

To sum up:
/ – via static system (WRONG)
/index.php – via fastcgi/php system (RIGHT)
/blah/ – via static system (WRONG)
/blah/index.php – via fastcgi/php system (RIGHT)

nginx version is 0.6.25, Help! :slight_smile:

tia,

  • mike

My Config File (the relevent bits anyway):

http {
upstream static-pool {
server 192.168.7.40:80;
server 192.168.7.41:80;
}

upstream php-fcgi-pool {
    server  192.168.7.40:7000;
    server  192.168.7.41:7000;
}

server {
    listen  80;
    root    /website/htdocs;
    index   index.php;
    fastcgi_index   index.php;
    include     /etc/nginx/fastcgi_params;

    location / {
        proxy_pass http://static-pool/website/htdocs/;
    }

    location ~ \.php$ {
        fastcgi_pass    php-fcgi-pool;
    }
}

}

Hello Mike,

Sunday, February 10, 2008, 12:32:14 PM, you wrote:

I have nginx set up as a load balancer in front of two machines
running fastcgi/php, and nginx for static content. The desired goal is
to have all php pages (including the site index pages of .*/index.php)
processed by the fastcgi/php upstream, and everything else provided by
the static servers. The following is what I have and what I believe
should have worked, but it appears to run all directory paths via the
static rule, rather than the php rule which matches the index.

To sum up:
/ – via static system (WRONG)
/index.php – via fastcgi/php system (RIGHT)
/blah/ – via static system (WRONG)
/blah/index.php – via fastcgi/php system (RIGHT)

nginx version is 0.6.25, Help! :slight_smile:

tia,

  • mike

My Config File (the relevent bits anyway):

http {
upstream static-pool {
server 192.168.7.40:80;
server 192.168.7.41:80;
}

upstream php-fcgi-pool {
    server  192.168.7.40:7000;
    server  192.168.7.41:7000;
}
server {
    listen  80;
    root    /website/htdocs;
    index   index.php;
    fastcgi_index   index.php;
    include     /etc/nginx/fastcgi_params;
    location / {
        proxy_pass http://static-pool/website/htdocs/;
    }
  •     location = / {
    
  •         fastcgi_pass    php-fcgi-pool;
    
  •     }
    
  •     location = /blah/ {
    
  •         fastcgi_pass    php-fcgi-pool;
    
  •     }

Thanks Denis. The problem w/ your solution is there is lots of
directories. I don’t want to have to create entries for each. I
suppose I could to a regex for .*/$ but some of the directories have
index.html instead of index.php, and I need to support that as well
:-(.

Any other options/suggestions?

  • mike

I tried that (iirc). The issue is that location / is processed first
(since it’s not a regex). but the regex doesn’t seem to apply after
the index file options are tacked on the end.

Why don’t you put

location ~ .php$ {
fastcgi_pass php-fcgi-pool;
}

before “location /” so that it can match first?

Kupo

I’d try something like the following:

location / {
if ($request_filename !~ “(.php|/)$”) {
proxy_pass http://static-pool/website/htdocs/;
}
}

set $dir_index index.php;

location ~ /$ {
set $index_php $root$uri$dir_index;
if (-f $index_php) {
fastcgi_pass php-fcgi-pool;
break;
}
proxy_pass http://static-pool/website/htdocs/;
}

location ~ .php$ {
fastcgi_pass php-fcgi-pool;
}

On Sun, Feb 10, 2008 at 03:14:36PM -0500, Kiril A. wrote:

Why don’t you put

location ~ .php$ {
fastcgi_pass php-fcgi-pool;
}

before “location /” so that it can match first?

No. See the processing order:
http://wiki.codemongers.com/NginxHttpCoreModule#location

On Sun, Feb 10, 2008 at 10:28:09PM -0500, Denis S. Filimonov wrote:

location ~ /$ {
}
There is no need of such spaghetti configuration:
all tests can be done via location regex and index directive.

I’ve gotten things to work OK w/ the following. It means I can’t have
more than one type of directory index, but it’s better than nothing.
Thanks for the suggestions all, and Igor, thanks for nginx period :-).

  • mike

    server {
    listen 80;
    root /website/htdocs;
    index index.php;
    fastcgi_index index.php;
    include /etc/nginx/fastcgi_params;

     location / {
         proxy_pass http://static-pool/website/htdocs/;
     }
    
     location ~ (\.php|/)$ {
         fastcgi_pass    php-fcgi-pool;
     }

On Sat, Feb 09, 2008 at 10:32:14PM -0800, Mike Javorski wrote:

/index.php – via fastcgi/php system (RIGHT)

}
    }
  •     location ~ /$ {
    
  •         fastcgi_pass    php-fcgi-pool;
    
  •     }
    

Then all “…/” will be handled by php-fcgi-pool.

On Mon, Feb 11, 2008 at 01:56:07PM -0800, Mike Javorski wrote:

I’ve gotten things to work OK w/ the following. It means I can’t have
more than one type of directory index, but it’s better than nothing.
Thanks for the suggestions all, and Igor, thanks for nginx period :-).

For local static files nginx can try several index files.
However, there is no way to learn existent index files on remote host.

On Monday 11 February 2008 01:53:36 Igor S. wrote:

 fastcgi_pass    php-fcgi-pool;

}

There is no need of such spaghetti configuration:
all tests can be done via location regex and index directive.

I believe the spaghetti is necessary to handle the following, I quote:

I suppose I could to a regex for .*/$ but some of the directories
have index.html instead of index.php, and I need to support that as well

In the configuration above, .*/$ locations will be passed to FastCGI
only if
there is an index.php and passed to the proxy otherwise.

On Mon, Feb 11, 2008 at 05:18:25PM -0500, Denis S. Filimonov wrote:

set $dir_index index.php;
location ~ .php$ {
have index.html instead of index.php, and I need to support that as well


In the configuration above, .*/$ locations will be passed to FastCGI only if
there is an index.php and passed to the proxy otherwise.

If nginx has access to these index files, then index directive tries
index.php and index.html and does internal redirect to index.php or
index.html.
The index.php will go to FastCGI.