How to enable Nginx to serve PHP code/pages in Ubuntu

The php5-cgi (until 5.2.4) package does not include a script to
automatically start it in external FASTCGI Mode (Daemon mode).

As there is some confusion on the Internet on how to properly set PHP
script execution in the Nginx Web server, I am attaching the script that
we reliably use at our UBUNTU Linux http://ubuntu.com/ servers.

We use Upstart, the Ubuntu’s native event-based replacement for the
sysvinit daemon.

This how we set it up:

sudo tee /etc/event.d/php-fastcgi <<-\EOA

/etc/event.d/php-fastcgi

php-fastcgi - starts php-cgi as an external FASTCGI process

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on runlevel 0
stop on runlevel 1
stop on runlevel 6
exec /usr/bin/sudo -u www-data PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=125 /usr/bin/php-cgi -q -b 127.0.0.1:9000
respawn
EOA

sudo chmod u+x /etc/event.d/php-fastcgi
sudo initctl start php-fastcgi # start php-fastcgi
sudo /etc/init.d/nginx restart

sudo initctl status php-fastcgi # check if upstart is supervising
ps aux | grep cgi # check the php-cgi running processes

sudo initctl stop php-fastcgi # stop php-fastcgi and all its childs.

Regards,

M.

This is how we install it in Ubuntu/Debian(sudo enabled):
sudo nano /etc/init.d/php-fastcgi # copy and paste the text between
the “— cut here —” to this file and save it (+x, Y, ).
sudo chmod u+x /etc/init.d/php-fastcgi
sudo chown 0.0 /etc/init.d/php-fastcgi
sudo update-rc.d php-fastcgi defaults 21 23

I hope it may also help you at your setups.

M.

— cut here —
#! /bin/sh

BEGIN INIT INFO

Provides: php-fastcgi

Required-Start: $all

Required-Stop: $all

Default-Start: 2 3 4 5

Default-Stop: 0 1 6

Short-Description: Start and stop php-cgi in external FASTCGI mode

Description: Start and stop php-cgi in external FASTCGI mode

END INIT INFO

Do NOT “set -e”

Default values are enclosed in []

PATH=/usr/sbin:/usr/bin:/sbin:/bin

Start php-fastcgi? [no]

START=yes

Read configuration data

NAME=php-fastcgi
DESC=“php-cgi runing in external FASTCGI mode”
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

Daemon pathname and args: IP=[127.0.0.1], port=[9000]

/usr/bin/php-cgi links to → /etc/alternatives/php-cgi →

/usr/bin/php5-cgi
DAEMON=/usr/bin/php-cgi
DAEMON_ARGS=“-q -b 127.0.0.1:9000”

Which user runs PHP? [www-data]

EXEC_AS_USER=www-data

php-cgi env. variables: spawned children [5] , concurrent requests

[1000]
PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=125
export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS

Exit if php-cgi is not installed

[ -x “$DAEMON” ] || exit 0

Load rcS variable settings and set (re)start/stop verbosity

[ -f /etc/default/rcS ] && . /etc/default/rcS
VERBOSE=yes

Define LSB log_* functions.

Depend on lsb-base (>= 3.0-6) to ensure that this file is present.

. /lib/lsb/init-functions

If $START not ‘yes’ AND we are not stopping the $DAEMON

if [ “$START” != “yes” -a “$1” != “stop” ]; then
log_warning_msg “To enable $NAME, edit /etc/init.d/$NAME and set
START=yes”
exit 0
fi

do_start()
{

Return values: 0=started ok,1=already running,2=unable to start

start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
–test > /dev/null || return 1
start-stop-daemon --start --quiet --background
–chuid $EXEC_AS_USER --pidfile $PIDFILE --make-pidfile
–exec $DAEMON – $DAEMON_ARGS
|| return 2
}

do_stop()
{

Return values: 0=stopped ok,1=already stopped,2=unable to stop,

other if a failure occurred

start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
  --pidfile $PIDFILE > /dev/null # --name $DAEMON

RETVAL=“$?”
[ “$RETVAL” = 2 ] && return 2

Wait for children to finish too.

start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5
–exec $DAEMON
[ “$?” = 2 ] && return 2

Many daemons don’t delete their pidfiles when they exit.

rm -f $PIDFILE
return “$RETVAL”
}

case “$1” in
start)
[ “$VERBOSE” != no ] && log_daemon_msg “Starting $DESC”
do_start
case “$?” in
0|1) [ “$VERBOSE” != no ] && log_end_msg 0 ;;
2) [ “$VERBOSE” != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ “$VERBOSE” != no ] && log_daemon_msg “Stopping $DESC”
do_stop
case “$?” in
0|1) [ “$VERBOSE” != no ] && log_end_msg 0 ;;
2) [ “$VERBOSE” != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg “Restarting $DESC”
do_stop
case “$?” in
0|1)
do_start
case “$?” in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo “Usage: $SCRIPTNAME {start|stop|restart|force-reload}” >&2
exit 3
;;
esac

— cut here —

On Mon, Nov 3, 2008 at 9:29 PM, Mark A. [email protected]
wrote:

The php5-cgi (until 5.2.4) package does not include a script to
automatically start it in external FASTCGI Mode (Daemon mode).

many said “use php-fpm”

http://www.yawn.it/2008/04/30/nginx-php-php-fpm-on-debian-etch-40/

I’m not using any Linux distro so I can’t help further.

+1 for php-fpm. It is the only way to do it. Don’t bother with
anything else.

Edho P Arief wrote:

many said “use php-fpm”

I have also read many things about php-fpm but…

  • you need to check that there are php-fpm patches for the specific PHP
    version that you intend to use;
  • you need to hand recompile PHP to use it,
  • you need to hand customize the paths of the recompiled code
  • you must comply with the awkward php-fpm license (non free/non OSI?)

And each time a new security/bug-fix release of PHP is out, you need to
start it all over again.

We still do prefer the Ubuntu “LESS IS MORE” way of doing things:
sudo aptitude update
sudo aptitude safe-upgrade

…and it is done!

After a few days of tests in the sandbox servers and after checking that
all is well, it is a simple matter of doing the same in the production
servers.

M.

On Mon, Nov 3, 2008 at 10:06 AM, Mark A. [email protected]
wrote:

  • you need to check that there are php-fpm patches for the specific PHP
    version that you intend to use;
  • you need to hand recompile PHP to use it,
  • you need to hand customize the paths of the recompiled code
  • you must comply with the awkward php-fpm license (non free/non OSI?)

the license isn’t a big deal and will be changed when it is feature
complete i am told, so it can be compatible with PHP core and
hopefully be merged.

And each time a new security/bug-fix release of PHP is out, you need to
start it all over again.

or you make a simple build script - i roll my own .deb file and
compile it only once, then deploy the .deb on all my servers. works
like a charm :slight_smile:

We still do prefer the Ubuntu “LESS IS MORE” way of doing things:
sudo aptitude update
sudo aptitude safe-upgrade

…and it is done!

except it might not have all the extensions you want or options you
want.

i use ubuntu repositories for -everything- and over the years have
slimmed down what i compile. nowadays it is only nginx, php-fpm and
ffmpeg for the most part - as ubuntu and other repositories are either
too outdated or not “rich enough” to meet my needs.

On Tuesday 04 November 2008, Edho P Arief wrote:

I’m also waiting for the day it’s merged with PHP core but currently
it’s the one of the best way to spawn and manage php-fcgi processes,
the other (not as good as using php-fpm) is using spawn-fcgi provided
by lighttpd (explained here
http://wiki.codemongers.com/NginxFcgiExample )

Wha’s the big deal about spawn-fcgi?
Why is i better than an one-liner shell script?

On Tue, Nov 4, 2008 at 8:42 PM, Roxis [email protected] wrote:

I don’t know really, perhaps because it works on most system?

Mark,

Thank you for this script. It may not be ideal for everyone, but it
will be
useful for many. Some people may not want to use PHP-FPM, so it isn’t
the
“only way” of doing business; and short, sweeping comments in response
to
someone sharing a helpful script are just plain rude. So, again, thanks
Mark!

– Adam

“Computers are useless. They can only give you answers.” — Pablo Picasso

On Tue, Nov 4, 2008 at 1:06 AM, Mark A. [email protected]
wrote:

Edho P Arief wrote:

many said “use php-fpm”

I have also read many things about php-fpm but…

  • you need to check that there are php-fpm patches for the specific PHP
    version that you intend to use;
  • you need to hand recompile PHP to use it,
    yes, unfortunately. Thankfully PHP isn’t released every other day.
  • you need to hand customize the paths of the recompiled code
    does it even matter? (–prefix ?)
  • you must comply with the awkward php-fpm license (non free/non OSI?)
    AFAIK it’s currently licensed under GPL

After a few days of tests in the sandbox servers and after checking that all
is well, it is a simple matter of doing the same in the production servers.

M.

I’m also waiting for the day it’s merged with PHP core but currently
it’s the one of the best way to spawn and manage php-fcgi processes,
the other (not as good as using php-fpm) is using spawn-fcgi provided
by lighttpd (explained here
http://wiki.codemongers.com/NginxFcgiExample )

don’t use spawn-fcgi as i’ve had first hand problems with it not
behaving properly.

instead if you won’t use php-fpm, just make a script that basically
does php-cgi -b $port (for TCP) - you can add in the environment
variables and sudo to make it run better - i wound up creating upstart
jobs in ubuntu (i think ~ 7.10 this is available)

this is my /etc/event.d/fastcgi-mike file:

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5

stop on shutdown

env PHP_FCGI_MAX_REQUESTS=250
env PHP_FCGI_CHILDREN=5

respawn
exec /usr/bin/sudo -u mike /usr/local/bin/php-cgi -b 10500

this allows for:

  • running as a different user id
  • one file per pool
  • auto startup on boot
  • “stop fastcgi-mike” and “start fastcgi-mike” for stopping/starting
    and it cleans it up properly
  • proper environment variable support, as opposed to my experience
    with spawn-fcgi ignoring PHP_FCGI_MAX_REQUESTS for example

php-fpm is the #1 option. #2 would be something like this (trigger it
how you like but this provides all the options one could want)

mike wrote:

env PHP_FCGI_MAX_REQUESTS=250
env PHP_FCGI_CHILDREN=5

respawn
exec /usr/bin/sudo -u mike /usr/local/bin/php-cgi -b 10500

This will not work.

php-cgi will not pick the values set by the env PHP_FCGI_ variables.
It will neither spwan the 5 children, nor obey the max_requests
directive.

I leave it to you, as an exercise, to discover why.

Could this be a reason why you need php-fpm where php-fpm is not needed?

M.

Depending on you feel about closed source software, LiteSpeed handles
PHP
very well. The free version is limited to 150 concurrent connections
but
offers an optimized protocol.

kind of the wrong direction for this list :stuck_out_tongue:

OP asked for how to get nginx to serve php. not swap it all out
completely :slight_smile:

i personally verified that it is in fact recycling the processes
(where spawn-fcgi -never- recycled even after the default 500 or
whatever it was) and it also spawned 5 children exactly how i told it
to.

i am curious to know why you say that.

also, i do consider php-fpm essential, otherwise i’d be managing
homebrew scripts to launch different fcgi pools (i have one per user)
with varying options and number of children, requests, etc. php-fpm
centralizes it and makes it very easy to use, graceful reloading, etc.
so no, i also disagree with your “not needed” statement. i tried
everything from apache + suexec + mod_fastcgi/mod_fcgid, mod_suphp,
spawn-fcgi, etc, etc. php-fpm was the cleanest method of managing all
the aspects i looked for, and will also soon introduce the apache
style process management which was one of the top two things i was
looking for.