Nginx, PHP and a PHP FastCGI daemon init script

One of the things us ex-Apache httpd or ex-Lighttpd users have to get used to when installing nginx is how there isn’t built-in FastCGI support for process spawning. While these means nginx is more lightweight and faster, it does mean that you have to manage your FastCGI processes yourself.

Having just upgraded to Ubuntu Feisty Fawn, I set to installing nginx and tried to get WordPress (which needs PHP, of course) running on it. Thanks to the new nginx package in the Feisty universe repository, getting nginx up and PHP (CGI version) and running is really straightforward. There’re lots of tutorials to help you out as well.

So that’s that. The part that bugged me though, was how the tutorials always provided a script to start your PHP FastCGI processes, but never provided a way to ensure your FastCGI processes started up on a reboot (i.e. an init script). Once again, Google doesn’t disappoint, turning up this php-cgi init script. Tweak the init script a little, put it in /etc/init.d/php-fastcgi, sudo chmod +x /etc/init.d/php-fastcgi, run sudo update-rc.d php-fastcgi defaults and place the configuration for the script in /etc/default/php-fastcgi, and you’re done. You now have a PHP FastCGI init script that spawns and kills your PHP FastCGI processes.

Note: Lighttpd does come with a spawn-fcgi binary that does the same, but I’m having trouble finding a suitable init script for spawn-fcgi (only the Gentoo emerge seems to have the init script). Still, this script works and I didn’t really want to install lightty on my starving VPS.

The init script: /etc/init.d/php-fastcgi

#! /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

# Author: Kurt Zankl <[EMAIL PROTECTED]>

# Do NOT “set -e”

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=”php-cgi in external FASTCGI mode”
NAME=php-fastcgi
DAEMON=/usr/bin/php-cgi
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
PHP_CONFIG_FILE=/etc/php5/cgi/php.ini

# Exit if the package is not installed
[ -x “$DAEMON” ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# If the daemon is not enabled, give the user a warning and then exit,
# unless we are stopping the daemon
if [ “$START” != “yes” -a “$1″ != “stop” ]; then
        log_warning_msg “To enable $NAME, edit /etc/default/$NAME and set START=yes”
        exit 0
fi

# Process configuration
export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
DAEMON_ARGS=”-q -b $FCGI_HOST:$FCGI_PORT -c $PHP_CONFIG_FILE”

do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon –start –quiet –pidfile $PIDFILE –exec $DAEMON –test > /dev/null \
                || return 1
        start-stop-daemon –start –quiet –pidfile $PIDFILE –exec $DAEMON \
                –background –make-pidfile –chuid $EXEC_AS_USER –startas $DAEMON — \
                $DAEMON_ARGS \
                || return 2
}

do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   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 if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.
        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” “$NAME”
        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” “$NAME”
        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” “$NAME”
        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

Config file for init script (the init script looks for this): /etc/default/php-fastcgi

START=yes

# Which user runs PHP? (default: www-data)

EXEC_AS_USER=www-data

# Host and TCP port for FASTCGI-Listener (default: localhost:9000)

FCGI_HOST=localhost
FCGI_PORT=9000

# Environment variables, which are processed by PHP

PHP_FCGI_CHILDREN=4
PHP_FCGI_MAX_REQUESTS=1000

nginx config file: /etc/nginx/nginx.conf

location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  /var/www/blog.codefront.net$fastcgi_script_name;
  include        /etc/nginx/fastcgi.conf;
}

My fastcgi.conf file (I’m not sure I need everything here…)

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

Trying to edit scripts and codes is pretty difficult on handheld computers, but attaching a small SATO printer to your mobile computer can make your data more accessible. If only there was a symbol scanner to help read website code!

19 Comments & TrackBacks (Add yours)

The paper doll icon that precedes each comment is an idea conceived by Vanessa Tan.

Paper doll icon
links for 2007-06-13 « Bloggitation's Gravatar

[…] Nginx, PHP and a PHP FastCGI daemon init script (tags: php web nginx fastcgi sysadmin) […]

Posted by: links for 2007-06-13 « Bloggitation on June 13, 2007 8am

Paper doll icon
Shannon -jj Behrens's Gravatar

I haven’t gotten it working yet, but I can make a couple corrections:

It’s not “/etc/defaults/php-fascgi”, it’s “/etc/default/php-fascgi”.

Beware when copying and pasting the above scripts. Double quotes and double hyphens get all messed up.

I’m currently stuck at “/etc/init.d/php-fastcgi start”. It’s just freezing without an error messages.

Posted by: Shannon -jj Behrens on June 14, 2007 3pm

Paper doll icon
Chu Yeow's Gravatar

Thanks for the corrections. I’ve fixed the typo, though I can’t figure out how to stop WordPress from “correcting” the quotes and hyphens in the code.

So it’s just freezing and you have to kill the script? It’s possible with the double hyphens and quotes madness there was a typo somewhere.

Posted by: Chu Yeow on June 14, 2007 3pm

Paper doll icon
David Currie » Blog Archive » Changing servers's Gravatar

[…] So, it’s been a little bit quiet on this blog for the past few days. The main reason is that it’s been on the move from the hosting provided by our ISP (PlusNet) to my SliceHost slice. Things would have been much quicker had I not decided to switch Apache for the increasingly popular (due to its low memory usage) nginx. As is the beauty of a virtual server, with the click of a mouse I had a clean Dapper Drake install to start with. Rather than install nginx from source, I decided to upgrade to Feisty Fawn and install via apt. This means losing the long term support of Dapper but, hey, its my server and I’ll just have to upgrade again when necessary. From there, getting an nginx, mysql, Rails and PHP setup is well documented, on top of which I added an init script for FastCGI. […]

Posted by: David Currie » Blog Archive » Changing servers on July 14, 2007 1am

Paper doll icon
Brian Acheson's Gravatar

Does a Fedora/RH equivalent of this script exist? I’ve been tweaking this to get it working on my Fedora machine, but have not had luck yet.

Thanks,
Brian

Posted by: Brian Acheson on July 22, 2007 6am

Paper doll icon
lejeczek's Gravatar

yes, fedora does have it, you could try: lighttpd-fastcgi it should give desired effects.

Posted by: lejeczek on August 16, 2007 8pm

Paper doll icon
mike503's Gravatar

i actually use ubuntu’s “upstart” init replacement, and spawn-fcgi from lighttpd


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

stop on shutdown

env PHP_FCGI_MAX_REQUESTS=125

respawn
exec /usr/bin/spawn-fcgi -u user -g group -C 5 -n -a 127.0.0.1 -p 1234 -f /usr/local/bin/php-cgi

then you can use “start $job” “stop $job” when you need it, and add that to your init script for starting/stopping the webserver (start engines prior to webserver starting, end engines after webserver ends)

works for me so far…

Posted by: mike503 on August 21, 2007 8am

Paper doll icon
osiris's Gravatar

hi,

difficult to make your scrip work. after correcting the quotes i have that new one:

/etc/init.d/php-fastcgi: 55: Syntax error: “||” unexpected. could you post a link to the raw script as .txt for instance? would be great. thank you

Posted by: osiris on August 28, 2007 12am

Paper doll icon
Gerry Kirk's Gravatar

Go to this page to download the script files above. Just follow the instructions step by step.

Posted by: Gerry Kirk on August 31, 2007 9pm

Paper doll icon
Here be dragons » Blog Archive » Nginx, fastcgi and wordpress ubuntu feisty's Gravatar

[…] relied on a number of helpful tutorials, none of which was a complete solution, so I figured as an opening offering I […]

Posted by: Here be dragons » Blog Archive » Nginx, fastcgi and wordpress ubuntu feisty on November 21, 2007 8am

Paper doll icon
Here With Me sur son nouveau serveur ! | Here With Me's Gravatar

[…] Tuto pour installer et configurer PHP5 via FastCGI avec Nginx […]

Posted by: Here With Me sur son nouveau serveur ! | Here With Me on December 3, 2007 4am

Paper doll icon
Nginx with PHP as FastCGI on Gentoo Linux | Tummblr's Gravatar

[…] Nginx, PHP and a PHP FastCGI daemon init script […]

Posted by: Nginx with PHP as FastCGI on Gentoo Linux | Tummblr on December 8, 2007 11am

Paper doll icon
Mandarin Soda » Blog Archive » Wordpress, PHP, Fastcgi, Nginx on Slicehost Sub-Domain's Gravatar

[…] Referenced: Primary Secondary Daemon script Nginx […]

Posted by: Mandarin Soda » Blog Archive » Wordpress, PHP, Fastcgi, Nginx on Slicehost Sub-Domain on December 14, 2007 4am

Paper doll icon
nginx + PHP + FastCGI???????? « ???'s Gravatar

[…] >Nginx, PHP and a PHP FastCGI daemon init script […]

Posted by: nginx + PHP + FastCGI???????? « ??? on January 14, 2008 1pm

Paper doll icon
Setup nginx for php and rails on Ubuntu Gutsy 7.10 » Big Blue Web Development's Gravatar

[…] Redemption in a Blog - Nginx, PHP and a PHP FastCGI daemon init script […]

Posted by: Setup nginx for php and rails on Ubuntu Gutsy 7.10 » Big Blue Web Development on January 24, 2008 8pm

Paper doll icon
~~????~~ » Blog Archive » Nginx???'s Gravatar

[…] Nginx, PHP and a PHP FastCGI daemon init script (with init script for PHP FastCGI) […]

Posted by: ~~????~~ » Blog Archive » Nginx??? on January 26, 2008 9pm

Paper doll icon
Installing nginx and PHP with FastCGI on Mac OS X 10.5 (Leopard) | Stephen Tudor's Gravatar

[…] Chu Yeow, who listed some awesome nginx config file examples. […]

Posted by: Installing nginx and PHP with FastCGI on Mac OS X 10.5 (Leopard) | Stephen Tudor on April 3, 2008 11am

Paper doll icon
Nginx, PHP and a PHP FastCGI daemon init script's Gravatar

[…] Nginx, PHP and a PHP FastCGI daemon init script 2008-05-08 | 10:34 ?????Nginx | ???FastCGI | Nginx, PHP and a PHP FastCGI daemon init script […]

Posted by: Nginx, PHP and a PHP FastCGI daemon init script on May 8, 2008 10pm

Paper doll icon
Where’s Lou » Blog Archive » Using NginX on Slicehost to save money's Gravatar

[…] Nginx, PHP and a PHP FastCGI daemon init script […]

Posted by: Where’s Lou » Blog Archive » Using NginX on Slicehost to save money on May 11, 2008 8am

You can subscribe to the RSS feed for comments on this post.

Post a comment

(required)

(required, but never displayed)


You can format your comments using XHTML. Your email address will not be displayed or used for nefarious purposes.

Only following tags are allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>