There is a new version of this tutorial available for Debian 12 (Bookworm).

Installing Nginx With PHP5 And MySQL Support On Debian Etch - Page 2

4 Installing PHP5

We can make PHP5 work in nginx through FastCGI. Fortunately, Debian provides a FastCGI-enabled PHP5 package which we install like this (together with some PHP5 modules like php5-mysql which you need if you want to use MySQL from your PHP scripts):

apt-get install php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-json php5-mcrypt php5-memcache php5-mhash php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Then open /etc/php5/cgi/php.ini and add the line cgi.fix_pathinfo = 1 right at the end of the file:

vi /etc/php5/cgi/php.ini
[...]
cgi.fix_pathinfo = 1

Then we create a php-fastcgi init script...

vi /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

# 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"


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

... make the file executable...

chmod 755 /etc/init.d/php-fastcgi

... and create another file, /etc/default/php-fastcgi, which you can use to control php-fastcgi (e.g. port to listen on, number of children and requests, etc.):

vi /etc/default/php-fastcgi
#
# Settings for php-cgi in external FASTCGI Mode
#

# Should php-fastcgi run automatically on startup? (default: no)

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=5
PHP_FCGI_MAX_REQUESTS=1000

Then we start php-fastcgi:

/etc/init.d/php-fastcgi start

To have php-fastcgi start at boot time, run

update-rc.d php-fastcgi defaults

 

5 Configuring nginx

The nginx configuration is in /usr/local/nginx/conf/nginx.conf which we open now:

vi /usr/local/nginx/conf/nginx.conf

The configuration is easy to understand (you can learn more about it here: http://wiki.codemongers.com/NginxFullExample and here: http://wiki.codemongers.com/NginxFullExample2)

First (this is optional) you can change the user and group it runs as (defaults to nobody/nogroup) to www-data and increase the number of worker processes and set the keepalive_timeout to a reasonable value:

[...]
user www-data www-data;
worker_processes  5;
[...]
    keepalive_timeout  2;
[...]

The virtual hosts are defined in server {} containers. Let's modify the default vhost as follows:

[...]
    server {
        listen       80;
        server_name  _;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.php index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html$fastcgi_script_name;
            include        fastcgi_params;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
[...]

server_name _; makes this a default catchall vhost (of course, you can as well specify a hostname here like www.example.com).

In the location / part, I've added index.php to the index line. root html; means that the document root is the directory html in the nginx directory => /usr/local/nginx/html. Of course, you can as well specify a full path here (e.g. /var/www/www.example.com/web).

The important part for PHP is the location ~ \.php$ {} stanza. Uncomment it to enable it. root html; translates to /usr/local/nginx/html again. Please make sure that you change the fastcgi_param line to fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; because otherwise the PHP interpreter won't find the PHP script that you call in your browser.

Now save the file and restart nginx:

/etc/init.d/nginx restart

Now create the following PHP file in the document root /usr/local/nginx/html...

vi /usr/local/nginx/html/info.php
<?php
phpinfo();
?>

Now we call that file in a browser (e.g. http://192.168.0.100/info.php):

As you see, PHP5 is working, and it's working through FastCGI, as shown in the Server API line. If you scroll further down, you will see all modules that are already enabled in PHP5, including the MySQL module:

 

Share this page:

1 Comment(s)