Nginx (pronounced Engine-X) is a lightweight web server, simple to use and configure. It’s perfect for handling static content, but is capable of much more (e.g. reverse proxy for mail protocols, FastCGI and etc.).

Nginx can handle quite a bit of load, thus it is used for high-load applications. You can read about it in webfaction.com blog: A little holiday present: 10,000 reqs/sec with Nginx!

According to their Wiki page, Nginx now serves 12.18% (22.2M) of all domains worldwide.

Here’s a bit more on Nginx:

Nginx and Lighttpd are probably the two best-known asynchronous servers and Apache is undoubtedly the best known process-based server. […] The main advantage of the asynchronous approach is scalability. In a process-based server, each simultaneous connection requires a thread which incurs significant overhead. An asynchronous server, on the other hand, is event-driven and handles requests in a single (or at least, very few) threads.

While a process-based server can often perform on par with an asynchronous server under light loads, under heavier loads they usually consume far too much RAM which significantly degrades performance. Also, they degrade much faster on less powerful hardware or in a resource-restricted environment such as a VPS.

Pulling numbers from thin air for illustrative purposes, serving 10,000 simultaneous connections would probably only cause Nginx to use a few megabytes of RAM whereas Apache would probably consume hundreds of megabytes (if it could do it at all).

I suggest you to read about it more here: http://www.wikivs.com/wiki/Apache_vs_nginx

Installing Nginx

**Before we start: **I will be installing Nginx on Ubuntu 11.10 machine, so if you’re using a different OS or Linux flavor (e.g. RedHat), not everything may apply to you.

To install Nginx you just need to fire up your Terminal (you may use Ctrl+Alt+T) and execute this command:

sudo apt-get update && sudo apt-get install nginx

This will download and install Nginx from Ubuntu repositories. It’s the easiest and quickest method, however authors recommend building it from source. That’s it! Nginx now should be installed, up and running (well, you might need to run it with sudo nginx command). Just point your browser to http://127.0.0.1 and you should see “Welcome to nginx!” text. If you do - we’re done with installing.

Installing and configuring FastCGI

To install PHP FastCGI we’ll just need to run this command:

sudo apt-get install php5-cgi

To spawn FastCGI processes, we’ll need to use these two scripts (Original author), provided on Nginx wiki:

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

:

Save this script as /etc/init.d/php-fastcgi

And we’ll need to save this one as /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=127.0.0.1
FCGI_PORT=9000

# Environment variables, which are processed by PHP

PHP_FCGI_CHILDREN=4
PHP_FCGI_MAX_REQUESTS=1000

After doing that, we’ll need to add this script to autostart to run this automatically every time the machine starts. Run these two commands in your Terminal:

<code>sudo chmod +x /etc/init.d/php-fastcgi
</code>sudo update-rc.d php-fastcgi defaults

And let’s launch it:

<code>sudo /etc/init.d/php-fastcgi start</code>

Configuring Nginx

We are ready to go! We just need to tweak Nginx configuration a bit.

First of all let’s create a demo file, which we’ll use to check if it works. For the sake of simplicity, let’s use /var/www folder for this. Run this command:

echo '<?php echo phpinfo(); ?>' > /var/www/index.php

Then let’s modify the default vhost. Open the configuration file /etc/nginx/sites-enabled/default

Find root /usr/share/nginx/www; **and replace it with **root /var/www/;

Add these lines inside server { … }

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;
}

Lastly we’ll need to restart nginx:

/etc/init.d/nginx restart

Go to http://127.0.0.1/index.php and if you can see the phpinfo() page - congratulations, you’ve done it!

Additional resources

While reading up on Nginx I found some pages, which may be helpful for you: