PHP on NGINX

December 19, 2011

I wanted to set up webmail on a Debian box running nginx, and the webmail software used PHP. To do this I used PHP as a fastcgi daemon and then proxied through to it from nginx.

PHP

First we install php:

apt-get install php5-cgi

We need to run php-fastcgi as a daemon. Here's the init.d script I used to do this:

#!/bin/bash

### BEGIN INIT INFO
# Provides:       php-fastcgi
# Required-Start: $local_fs $syslog
# Required-Stop:  $local_fs $syslog
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description: php-fastcgi
### END INIT INFO

BIND=127.0.0.1:9099
USER=www-data
GROUP=www-data
PHP_FCGI_CHILDREN=1
PHP_FCGI_MAX_REQUESTS=1000

PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER GROUP=$GROUP PATH=/usr/bin"
PHP_CGI_ARGS="$PHP_CGI_ARGS PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN"
PHP_CGI_ARGS="$PHP_CGI_ARGS PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0

start() {
      echo -n "Starting PHP FastCGI: "
      start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
      RETVAL=$?
      echo "$PHP_CGI_NAME."
}
stop() {
      echo -n "Stopping PHP FastCGI: "
      killall -q -w -u $USER $PHP_CGI
      RETVAL=$?
      echo "$PHP_CGI_NAME."
}

case "$1" in
    start)
      start
  ;;
    stop)
      stop
  ;;
    restart)
      stop
      start
  ;;
    *)
     echo "Usage: php-fastcgi {start|stop|restart}"
      exit 1
  ;;
esac
exit $RETVAL

Next we need to proxy to 127.0.0.1:9099 whenever a php request comes in:

server {
    listen          443 default;
    server_name     domain.co.uk;

    ssl                     on;
    ssl_certificate         /path/to/cert.crt;
    ssl_certificate_key     /path/to/cert.key;

    access_log  /home/drumcoder/log/site-access.log;

    if ($host ~* www\.(.*)) {
            set $host_without_www $1;
            rewrite ^(.*)$ http://$host_without_www$1 permanent;
    }

    location / {
            root            /home/drumcoder/web/domain.co.uk;
            index           index.html;
    }

    location ~ /mailoffset/.+\.php {
            root            /home/drumcoder/web/domain.co.uk;
            fastcgi_index   index.php;

            include         /etc/nginx/fastcgi_params;
            keepalive_timeout 0;
            fastcgi_param   SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
            fastcgi_pass    127.0.0.1:9099;
    }
}

Note that we only support php for urls that start /mailoffset/ - the rest of the domain does not have php support, for security reasons.

References

Tags: php nginx fastcgi cgi