Please help me get FastCGI working with nginx

I’ve spent the past several days going around and around trying to get
FastCGI working with Nginx and I am stuck. Hopefully someone here can
guide me please.

In summary I am trying to use nginx to front-end a PHP web site (instead
of using Apache/PHP I want to us Nginx/PHP).

I have a working nginx 0.6.latest.ver working without PHP and FastCGI
support, as I’ve used nginx plenty in the past. So now I am trying to
add PHP and FastCGI into the picture but am totally stuck…

The first thing I did was download and compile PHP with FastCGI support:

…/configure --enable-mbstring --with-mysql=/usr/bin
–with-mysql-sock=/mnt/mysql/data/mysql.sock --enable-fastcgi
–with-curl --enable-sockets --with-config-file-path=\etc

make
make install

So that goes OK.

But then when I run /usr/local/bin/php -v it says:
PHP 5.2.6 (cli) (built: Aug 3 2008 23:45:09)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies

I read somewhere that if that output says “(cli)” and not “(fast-cgi)”
then PHP is not installed with FastCGI support. So perhaps this is my
issue.

However as you can see from my ./configure command for PHP included
above, I am specifying --enable-fastcgi which according the several web
sites and the “.configure --help” says is all that is needed.

Am I missing something here?

Then based on pages like http://wiki.codemongers.com/NginxFcgiExample I
am doing this:
/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 8888 -f /usr/local/bin/php

and it exists with this:
spawn-fcgi.c.218: child exited with: 0, Success

However when I do a “ps -A” I don’t see spawn-fcgi running. Furthermore
if I telnet to port 8888 on localhost it says connection refused so I
don’t think anything is listening there.

So then of course when I try a .php page on nginx I get this in its
error log:
connect() failed (111: Connection refused) while connecting to upstream,
client: x.y.z.a, server: localhost, request: “GET /test.php5 HTTP/1.1”,
upstream: “fastcgi://127.0.0.1:8888”, host: “myhost”

Can someone please point me in the right direction? Any tips are GREATLY
appreciated! Also is there any chance we will get FastCGI natively
implemented in nginx like it is with Apache and other servers? Thank you
so much in advance!!

Use php-fpm. It makes I so much easier. The spawn-fcgi stuff sucks.

In the php-fpm.conf you can configure the tcp port or socket and just
tell nginx to use that. It’s pretty simple. I also recommend running
tcp instead of sockets and binding to localhost unless you need to
access it from another machine

On Mon, Aug 4, 2008 at 12:44 PM, mike [email protected] wrote:

Use php-fpm. It makes I so much easier. The spawn-fcgi stuff sucks.

In the php-fpm.conf you can configure the tcp port or socket and just tell nginx to use that. It’s pretty simple. I also recommend running tcp instead of sockets and binding to localhost unless you need to access it from another machine

any reason why tcp instead of sockets?

also, uh… Rt Ibmer - nginx supports fastcgi “natively” already, what
are you talking about? I second php-fpm as well, btw (although, this
is from somebody who hasn’t used fastcgi much, so take it with a pinch
of salt… It is easy to setup, configure, and understand, that’s for
sure!)

-jf

On 8/4/08, Jeffrey ‘jf’ Lim [email protected] wrote:

any reason why tcp instead of sockets?

Various people have complained and switching to TCP fixed it. I’ve
heard in the past of socket issues with a lot of data… but I’ve
never had an issue with TCP and I’ve been using it for years
(regardless of webserver and using PHP-FPM or not)

Those kind of socket performance issues/crashes could be a thing of
the past, but my solution works and I don’t see a need to ever try
sockets since TCP has worked since day 1 (and I don’t think it can
really get any faster for me)

mike wrote:

Use php-fpm. It makes I so much easier. The spawn-fcgi stuff sucks.

In the php-fpm.conf you can configure the tcp port or socket and just
tell nginx to use that. It’s pretty simple. I also recommend running tcp
instead of sockets and binding to localhost unless you need to access it
from another machine

In my own experience unix socket is better in terms of speed when
nginx and PHP are on the same computer. My test was made with httperf
and show a better rate (req/s) with PHP/FastCGI using unix socket. Why
do you recommend tcp socket ?

(…)

Stéphane Bunel.

On Sun, Aug 03, 2008 at 21:26:24, Rt Ibmer said…

Can someone please point me in the right direction? Any tips are GREATLY
appreciated! Also is there any chance we will get FastCGI natively
implemented in nginx like it is with Apache and other servers? Thank you so
much in advance!!

It is already “natively implemented” - or are you referring to Apache’s
ability
to dynamically spawn FastCGI servers?

On 8/4/08, Stephane B. [email protected] wrote:

In my own experience unix socket is better in terms of speed when nginx and
PHP are on the same computer. My test was made with httperf and show a
better rate (req/s) with PHP/FastCGI using unix socket. Why do you recommend
tcp socket ?

Like I said, various reports in the past. I’m pretty sure just within
the last couple months someone mentioned on here (or maybe it was the
PHP/PHP-FPM list) having some sporadic issues, he was using sockets,
he changed to TCP and had no issues. I also said that for all I know
all the socket issues have been fixed now on modern day stuff. But I
have no reason or care to try them myself.

I am serving up requests pretty much as fast as they can be served now
it seems like. I have a real world load and don’t need to benchmark to
see if I can squeeze out an extra 100 requests per second, as that
would require the database to be doing 100 more page loads worth of
work per second too, etc. When I need to scale up or out, I will pick
the appropriate place. Most likely the database will need scaling, not
my php+fastcgi stuff. But I’ve actually been able to scale my
webserver/php+fastcgi setup down to 3 servers from 4 even without an
issue. I think I have plenty of room to grow still using TCP.

seems from your mail that you might want to try running
/usr/local/bin/
php-cgi instead of /usr/local/bin/php. php is the CLI
version, php-cgi
is the cgi/fcgi version.

A big thanks to you and the others that replied! The above turned out
to be my issue. I was not aware that the php-cgi was created as its own
binary.

As has been said, php-fpm is probably the smart way to go,

I applied the php-fpm path and rebuilt - things seem to be working
great!

One question though - what are you guys using for start/stop scripts for
php-fpm upon boot up?

Is it just a simple matter of making a startup script in init.d that
just does “/path/php-cgi --fpm” ? Or is there something else important
that I am missing as far as startup/shutdown go?

I was thinking of also perhaps adding some switches like restart workers
and reopening logs to the startup script that would then look up the PID
and send the appropriate signal accordingly. If someone else has
already done so or has a startup script they can share can you please
post it?

Thanks again for the tremendous help all!

It is already “natively implemented” - or are you
referring to Apache’s ability
to dynamically spawn FastCGI servers?

Correct - I am referring to Apach’e ability to dynamically spawn FastCGI
servers. I’m not sure what if any advantage there would be to that
compared to using php-fpm (very nice BTW!) which I now have working,
other than perhaps the fact that it would be more of an out of the box
solution.

On Mon 04.08.2008 10:50, Rt Ibmer wrote:

One question though - what are you guys using for start/stop scripts
for php-fpm upon boot up?

Is it just a simple matter of making a startup script in init.d that
just does “/path/php-cgi --fpm” ? Or is there something else important
that I am missing as far as startup/shutdown go?

there is a /sbin/php-fpm for this.

Cheers

Aleks

Symlink /usr/local/bin/php-fpm to /etc/init.d/php-fpm

Yeah I was going to mention the php-cgi binary too but php-fpm takes
care of all of your needs :slight_smile:

Hi,

As has been said, php-fpm is probably the smart way to go, but it
seems from your mail that you might want to try running /usr/local/bin/
php-cgi instead of /usr/local/bin/php. php is the CLI version, php-cgi
is the cgi/fcgi version.

cheers
i

Perfect! It works great. As a side note I had to add a chkconfig and
description to the comments to make it compatible with chkconfig under
Fedora 8.

Also one other question please - why is it when I purposely request a
PHP page that doesn’t exist (as a test) the browser returns “No input
file specified.” instead of the standard 404 page?

I can see in the nginx log file it logs a 404 as expected, so not sure
what I’m doing wrong. I also have this:
proxy_intercept_errors on;

declared in the location block that handles the fastCgi forwarding. Am I
missing something needed to get the 404 page? Thanks again!

Php-fpm will do apache style php process management soon to adapt to
load. That’s one of the best features it will offer :slight_smile:

On Mon, Aug 04, 2008 at 02:34:28PM -0700, Rt Ibmer wrote:

Perfect! It works great. As a side note I had to add a chkconfig and description to the comments to make it compatible with chkconfig under Fedora 8.

Also one other question please - why is it when I purposely request a PHP page that doesn’t exist (as a test) the browser returns “No input file specified.” instead of the standard 404 page?

I can see in the nginx log file it logs a 404 as expected, so not sure what I’m doing wrong. I also have this:
proxy_intercept_errors on;

declared in the location block that handles the fastCgi forwarding. Am I missing something needed to get the 404 page? Thanks again!

You need
fastcgi_intercept_errors on;

purposely request a PHP page that doesn’t exist (as a
test) the browser returns “No input file
specified.” instead of the standard 404 page?

You need
fastcgi_intercept_errors on;

Thanks. I did that, but then had to also use the error_page directive to
point it at my 404.php page.

However this has the undesirable effect of then changing the URL in the
browser to 404.php.

Is there a way I can have nginx return the content of my 404.php page as
the output, so the user still sees their bad page in the URL (i.e.
http://www.mysite.com/badpage.php instead of
http://www.mysite.com/404.php)?

Thank you.

I currently do this in my location block
location ~ .*.php$ {
if (!-f $request_filename) {
return 404;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}

This way when it goes to process the php files if it is not found then
returns a 404 instead of passing it onto php and getting the no input
file
error.

On Mon, Aug 04, 2008 at 06:06:02PM -0700, Rt Ibmer wrote:

Is there a way I can have nginx return the content of my 404.php page as the output, so the user still sees their bad page in the URL (i.e. http://www.mysite.com/badpage.php instead of http://www.mysite.com/404.php)?

  location ~* \.php$ {

       fastcgi stuff

       fastcgi_intercept_errors  on;
       error_page   404  /404.php;
  }

On Mon, Aug 04, 2008 at 18:06:02, Rt Ibmer said…

However this has the undesirable effect of then changing the URL in the
browser to 404.php.

Is there a way I can have nginx return the content of my 404.php page as the
output, so the user still sees their bad page in the URL (i.e.
http://www.mysite.com/badpage.php instead of http://www.mysite.com/404.php)?

I tend to just handle this inside my application, rather than
redirecting to a
static page. For all but really fatal errors, that is, and those tend
to be in
the 500 range anyways.