De Apache a nginx

Antes había usado Cherokee (antes de que tuviese interface de administración bonita) y había terminado usando Apache de nuevo por unos problemitas con la configuración, sobre todo los rewrite de WordPress y Drupal que se terminaban en una pesadilla para mi, más no es que lo sean ahorita, realmente ni sé como se maneja en Cherokee actualmente esto.

Ahora, dejándome llevar un poco por la moda y sobre todo por los 300 y algo MB de RAM que tengo en el nodo de Linode me vi en la necesidad de bajar el consumo de memoria y mi opción inmediata fue nginx. Mi primera necesidad era que corriese PHP para montar Wordpress y conseguí que es facilísimo configurar los VirtualHosts, consume el mínimo de memoria y corre rapidísimo.

La instalación facilísima, lo hice en Debian Stable, si lo hacen en >Stable no necesitarán los últimos 3 sino spawn-fcgi:

# aptitude update
#aptitude install nginx php5-cli php5-cgi build-essential wget psmisc

¿Por qué build-essential, wget y psmisc? Porque se necesita para compilar spawn-fcgi que luego usaremos para PHP.

Si has usado Apache verás que la estructura es parecidísima, se configuran en /etc/nginx/sites-available/ y se copia o hacen enlaces simbólicos hacia /etc/nginx/sites-enabled/, recomiendo usar el último método para facilidad de administración.

Así se terminó viendo uno de los archivos de configuración local para hacer las pruebas del servidor:

server {
    listen 80;
    server_name localhost;
    access_log /home/ghostbar/tmp/boo_access.log;
    error_log /home/ghostbar/tmp/boo_error.log;

    location / {
        root    /var/www/w;
        index   index.php;
        
        if (-f $request_filename) {
            expires 30d;
            break;
        }

        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?q$1 last;
        }
        include /etc/nginx/expire_headers;
    }

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:56123;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/w$fastcgi_script_name;
    }
}

La línea para rewrite funciona perfectamente para WordPress y garantiza que funcionará sin activar absolutamente nada más en WordPress.

El contenido de /etc/nginx/expire_headers es el que copiaré a continuación, sin embargo, no lo necesitan. /etc/nginx/fastcgi_params viene con la instalación de nginx al menos en Debian 5.

if ($request_uri ~*    "\.(ico|gif|png|jpe?g|css|js|swf)(\?v\d\d?\.\d\d?\.\d\d?)?$") {
      expires max;
        break;
}

Muy bien, ahora configurando para que PHP funcione con spawn-fcgi:

Descárguese spawn-fcgi, en este momento funciona:

$ cd /tmp
$ wget http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz
$ tar -zxf spawn-fcgi-1.6.3.tar.gz
$ cd spawn-fcgi-1.6.3/
$ ./configure
$ make
$ sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi

Créese el archivo /usr/bin/php-fastcgi con la siguiente información:

#!/bin/sh
exec 2>&1
PHP_FCGI_CHILDREN=2 \
PHP_FCGI_MAX_REQUESTS=1000 \
exec /usr/bin/spawn-fcgi -a 127.0.0.1 -p 12345 -u www-data -f /usr/bin/php5-cgi

Las razones por las que le paso esas variables a spawn-fcgi es porque suele fallar sin razón sin usar PHP_FCGI_MAX_REQUESTS y PHP_FCGI_CHILDREN hace de que hayan 2 procesos y no se recargue uno de ellos, esto garantiza mayor fluidez en la ejecución de los scripts PHP.

Ahora el demonio para PHP, yo lo llamé /etc/init.d/php-fastcgi:

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

Le decimos al sistema que inicie el demonio cuando prendamos la máquina con:

# update-rc.d php-fastcgi defaults

Y ya, ahora a darle permisos de ejecución a /etc/init.d/php-fastcgi, /usr/bin/php-fastcgi y /usr/bin/spawn-fcgi e iniciar los demonios nginx y php-fastcgi con:

# /etc/init.d/nginx start
# /etc/init.d/php-fastcgi start

La migración de Apache a nginx como verán es casi directa, sólo adaptar los VirtualHosts a la nueva sintáxis que es sencillísima de entender.

Pasé de usar 289MB de RAM en mi nodo a 118MB con 4 procesos PHP y 6 procesos de nginx.

Any comment goes best to my twitter here.