installing Nginx with php fast-cgi on Ubuntu

Nginx is an awesome webserver and reverse proxy that is feature rich and super fast. Perwiki.nginx.org here is the description of the server:

———————————————————————————————————-

Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Igor Sysoev started development of Nginx in 2002, with the first public release in 2004. Nginx now hosts nearly 6% (13M) of all domains worldwide.

Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.

Nginx is one of a handful of servers written to address the C10K problem. Unlike traditional servers, Nginx doesn’t rely on threads to handle requests. Instead it uses a much more scalable event-driven (asynchronous) architecture. This architecture uses small, but most importantly,predictable amounts of memory under load.
Even if you don’t expect to handle thousands of simultaneous requests, you can still benefit from Nginx’s high-performance and small memory footprint. Nginx scales in all directions: from the smallest VPS all the way up to clusters of servers.

———————————————————————————————————-

Let’s go over a basic installation.

Step 1. installing Nginx and php via apt

# apt-get install nginx php5-cgi

Step 2. Create a /usr/bin/php-fastcgi file and add the following to it:

#!/bin/sh
/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -f /usr/bin/php5-cgi

Then chmod it to be executable as is this the command that will be used to spawn the fastcgi server:

# chmod +x /usr/bin/php-fastcgi

Step 3. Create the file /etc/init.d/init-fastcgi and put the following in it:

#!/bin/bash
PHP_SCRIPT=/usr/bin/php-fastcgi
RETVAL=0
case "$1" in
    start)
      $PHP_SCRIPT
      RETVAL=$?
  ;;
    stop)
      killall -9 php
      RETVAL=$?
  ;;
    restart)
      killall -9 php
      $PHP_SCRIPT
      RETVAL=$?
  ;;
    *)
      echo "Usage: php-fastcgi {start|stop|restart}"
      exit 1
  ;;
esac
exit $RETVAL

Then chmod it to be executable as well:

# chmod +x /etc/init.d/init-fastcgi

Step 5. Use updaterc.d to add the init script to boot time:

# update-rc.d init-fastcgi defaults
update-rc.d: warning: /etc/init.d/init-fastcgi missing LSB information
update-rc.d: see
 Adding system startup for /etc/init.d/init-fastcgi ...
   /etc/rc0.d/K20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc1.d/K20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc6.d/K20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc2.d/S20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc3.d/S20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc4.d/S20init-fastcgi -> ../init.d/init-fastcgi
   /etc/rc5.d/S20init-fastcgi -> ../init.d/init-fastcgi

Step 6. Configure the vhost in /etc/nginx/sites-enabled/default as needed and to pass php to the fastcgi server:

Example

# cat /etc/nginx/sites-enabled/default
# You may add here your
# server {
# ...
# }
# statements for each of your virtual hosts

server {
 listen   80;
 server_name  internal;

 access_log  /var/log/nginx/localhost.access.log;

 location / {
  root   /var/www;
         if (!-e $request_filename) {
         rewrite ^/(.+)$ /?q=$1 last;
      }

  index  index.html index.htm index.php;
 }

 location /doc {
  root   /usr/share;
  autoindex on;
  allow 127.0.0.1;
  deny all;
 }

 location /images {
  root   /usr/share;
  autoindex on;
 }

 #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   /var/www/nginx-default;
 #}

 # 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$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME   /var/www/$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;
 #}
}

# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#listen   8000;
#listen   somename:8080;
#server_name  somename  alias  another.alias;

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

# HTTPS server
#
#server {
#listen   443;
#server_name  localhost;

#ssl  on;
#ssl_certificate  cert.pem;
#ssl_certificate_key  cert.key;

#ssl_session_timeout  5m;

#ssl_protocols  SSLv2 SSLv3 TLSv1;
#ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
#ssl_prefer_server_ciphers   on;

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

Step 7. Start Nginx and the init-fastcgi script:

/etc/init.d/nginx start; /etc/init.d/init-fastcgi start

Hints:

You can easily check if the services are running via netstat:

# netstat -anp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      12392/nginx
unix  3      [ ]         STREAM     CONNECTED     47780    12392/nginx
unix  3      [ ]         STREAM     CONNECTED     47779    12392/nginx
d# netstat -anp | grep php
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      12333/php5-cgi

Also, if you encounter any configuration errors with Nginx this command will help:

d# /etc/init.d/nginx configtest
Testing nginx configuration: the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful
nginx.

This command is just like apachectl configtest and will give you the line of the error file.

Create a file named /usr/bin/php-fastcgi with the following contents:

File:/usr/bin/php-fastcgi

#!/bin/bash

FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
SOCKET=/var/run/php-fastcgi/php-fastcgi.socket
PIDFILE=/var/run/php-fastcgi/php-fastcgi.pid
CHILDREN=6
PHP5=/usr/bin/php5-cgi

/usr/bin/spawn-fcgi -s $SOCKET -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

Make it executable by issuing the following command:

chmod +x /usr/bin/php-fastcgi

TCP Sockets Configuration Example

Alternately, you may wish to use TCP sockets instead. If so, modify your nginx virtual host configuration file to resemble the following example. Again, make sure to replace all instances of “example.com” with your domain name.

File:/etc/nginx/sites-available/www.example.com

server {
    server_name www.example.com example.com;
    access_log /srv/www/www.example.com/logs/access.log;
    error_log /srv/www/www.example.com/logs/error.log;
    root /srv/www/www.example.com/public_html;

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

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
    }
}

Create a file named /usr/bin/php-fastcgi with the following contents:

File:/usr/bin/php-fastcgi

#!/bin/bash

FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
ADDRESS=127.0.0.1
PORT=9000
PIDFILE=/var/run/php-fastcgi/php-fastcgi.pid
CHILDREN=6
PHP5=/usr/bin/php5-cgi

/usr/bin/spawn-fcgi -a $ADDRESS -p $PORT -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

Make it executable by issuing the following command:

chmod +x /usr/bin/php-fastcgi

Important Security Considerations

If you’re planning to run applications that support file uploads (images, for example), the above configurations may expose you to a security risk by allowing arbitrary code execution. The short explanation for this behavior is that a properly crafted URI which ends in “.php”, in combination with a malicious image file that actually contains valid PHP, can result in the image being processed as PHP.

To mitigate this issue, you may wish to modify your configuration to include a try_files directive. Please note that this fix requires nginx and the php-fcgi workers to reside on the same server.

location ~ \.php$ {
    try_files $uri =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
}

Additionally, it’s a good idea to secure any upload directories your applications may use. The following configuration excerpt demonstrates securing an “/images” directory.

location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
    if ($uri !~ "^/images/") {
        fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
    }
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
}

Enable and Start Services

Issue the following commands to enable the site:

cd /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/www.example.com

Create a file named /etc/init.d/php-fastcgi with the following contents:

File:/etc/init.d/php-fastcgi

#!/bin/bash

PHP_SCRIPT=/usr/bin/php-fastcgi
FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
PID_DIR=/var/run/php-fastcgi
PID_FILE=/var/run/php-fastcgi/php-fastcgi.pid
RET_VAL=0

case "$1" in
    start)
      if [[ ! -d $PID_DIR ]]
      then
        mkdir $PID_DIR
        chown $FASTCGI_USER:$FASTCGI_GROUP $PID_DIR
        chmod 0770 $PID_DIR
      fi
      if [[ -r $PID_FILE ]]
      then
        echo "php-fastcgi already running with PID `cat $PID_FILE`"
        RET_VAL=1
      else
        $PHP_SCRIPT
        RET_VAL=$?
      fi
  ;;
    stop)
      if [[ -r $PID_FILE ]]
      then
        kill `cat $PID_FILE`
        rm $PID_FILE
        RET_VAL=$?
      else
        echo "Could not find PID file $PID_FILE"
        RET_VAL=1
      fi
  ;;
    restart)
      if [[ -r $PID_FILE ]]
      then
        kill `cat $PID_FILE`
        rm $PID_FILE
        RET_VAL=$?
      else
        echo "Could not find PID file $PID_FILE"
      fi
      $PHP_SCRIPT
      RET_VAL=$?
  ;;
    status)
      if [[ -r $PID_FILE ]]
      then
        echo "php-fastcgi running with PID `cat $PID_FILE`"
        RET_VAL=$?
      else
        echo "Could not find PID file $PID_FILE, php-fastcgi does not appear to be running"
      fi
  ;;
    *)
      echo "Usage: php-fastcgi {start|stop|restart|status}"
      RET_VAL=1
  ;;
esac
exit $RET_VAL

Start php-fastcgi and nginx by issuing the following commands:

chmod +x /etc/init.d/php-fastcgi
update-rc.d php-fastcgi defaults
/etc/init.d/php-fastcgi start
/etc/init.d/nginx start

Conclusion:
Nginx is an awesome free alternative to lightspeed in the webserver arena. I hope this article will help guide you through the installation of Nginx and if I missed anything let me know and I’ll add it.

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *