Hace poco adquirí un VPS de 256 MB en slicehost. Para ahorrar RAM decidí utilizar nginx como servidor web en lugar de Apache.
La web que estoy montando en este VPS constará de una aplicación rails y de un blog basado en WordPress, por lo que será necesario PHP. En este post contaré cómo configurar un virtual host de nginx para que sirva una aplicación PHP mediante FastCGI. La distribución que utilizo es Debian Etch.
Instalación de nginx
Para poder disponer de la última versión estable de nginx (0.5.35) compilaremos el código. El primer paso será instalar algunos paquetes necesarios:
sudo aptitude install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev
El “sbin-path” por defecto es “/usr/local/nginx/sbin”, así que al configure le indicaremos uno más conveniente: “/usr/local/sbin”. Asimismo, la compilación la realizaremos con soporte para SSL:
wget http://sysoev.ru/nginx/nginx-0.5.35.tar.gz tar zxf nginx-0.5.35.tar.gz cd nginx-0.5.35/ ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module make sudo make install
Cuando termina el configure obtenemos un resumen con los ficheros más importantes:
nginx path prefix: "/usr/local/nginx" nginx binary file: "/usr/local/sbin" nginx configuration file: "/usr/local/nginx/conf/nginx.conf" nginx pid file: "/usr/local/nginx/logs/nginx.pid" nginx error log file: "/usr/local/nginx/logs/error.log" nginx http access log file: "/usr/local/nginx/logs/access.log" nginx http client request body temporary files: "/usr/local/nginx/client_body_temp" nginx http proxy temporary files: "/usr/local/nginx/proxy_temp" nginx http fastcgi temporary files: "/usr/local/nginx/fastcgi_temp"
Arrancamos nginx:
sudo /usr/local/sbin/nginx
y comprobamos que funciona introduciendo en el navegador nuestra URL:
http://midominio.com/
Lo único que nos queda para tener nginx funcionando es crear un script que arranque el servidor web cuando arranque el VPS:
sudo kill `cat /usr/local/nginx/logs/nginx.pid` sudo vi /etc/init.d/nginx sudo chmod +x /etc/init.d/nginx sudo /usr/sbin/update-rc.d -f nginx defaults
Siendo /etc/init.d/nginx:
#! /bin/sh ### BEGIN INIT INFO # Provides: nginx # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the nginx web server # Description: starts nginx using start-stop-daemon ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/local/sbin/nginx NAME=nginx DESC=nginx test -x $DAEMONexit 0 # Include nginx defaults if available if [ -f /etc/default/nginx ] then . /etc/default/nginx fi set -e case "$1" in start) echo -n "Starting $DESC: " start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid \ --exec $DAEMON -- $DAEMON_OPTS echo "$NAME." stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid \ --exec $DAEMON echo "$NAME." restart force-reload) echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --pidfile \ /usr/local/nginx/logs/nginx.pid --exec $DAEMON sleep 1 start-stop-daemon --start --quiet --pidfile \ /usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS echo "$NAME." reload) echo -n "Reloading $DESC configuration: " start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid \ --exec $DAEMON echo "$NAME." *) N=/etc/init.d/$NAME echo "Usage: $N {start stop restart force-reload}" >&2 exit 1 esac exit 0
Configuración del virtual host de nginx que servirá PHP
Supongamos que el virtual host de nginx en el que funcionará el blog basado en WordPress es blog.midominio.com. En este caso, en el fichero de configuración de nginx, que será /usr/local/nginx/conf/nginx.conf, tendremos que añadir, de momento:
server {
listen 80
server_name blog.midominio.com
access_log /var/log/nginx/blog.midominio.com/access.log
error_log /var/log/nginx/blog.midominio.com/error.log
location / {
root /var/www/blog.midominio.com
index index.html
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html
location = /50x.html {
root html
}
} El directorio para los logs, /var/log/nginx/blog.midominio.com, y el directorio para las páginas, /var/www/blog.midominio.com, pueden ser otros. En cualquier caso, los deberemos crear a mano. Después de cualquier cambio en el fichero de configuración de nginx es necesario un restart:
sudo /etc/init.d/nginx restart
Llegados a este punto, podemos crear un index.html en /var/www/blog.midominio.com y ver que carga correctamente en el navegador:
http://blog.midominio.com/
Instalación de PHP
La instalación de PHP es realmente sencilla:
$ sudo apt-get install php5-cli php5-cgi php5-mysql $ php -v PHP 5.2.0-8+etch9 (cli) (built: Dec 29 2007 14:49:25) Copyright (c) 1997-2006 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
Instalación de FastCGI
La implementación de FastCGI que vamos a utilizar es la que viene con lighttpd. Lo que haremos será compilar lighttpd, pero no instalarlo. Copiaremos a mano el proceso spawn-fcgi:
wget http://www.lighttpd.net/download/lighttpd-1.4.18.tar.gz gunzip lighttpd-1.4.18.tar.gz tar xvf lighttpd-1.4.18.tar cd lighttpd-1.4.18/ ./configure make sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi
Ahora que ya tenemos FastCGI, crearemos un script para lanzarlo, al que llamaremos /usr/bin/php-fastcgi, y cuyo contenido será:
#!/bin/sh /usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -f /usr/bin/php5-cgi
Crearemos también el script de arranque y parada para cuando rearranquemos el servidor. Le llamaremos /etc/init.d/php-fastcgi, y su contenido será:
#!/bin/bash
PHP_SCRIPT=/usr/bin/php-fastcgi
RETVAL=0
case "$1" in
start)
$PHP_SCRIPT
RETVAL=$?
stop)
killall -9 php5-cgi
RETVAL=$?
restart)
killall -9 php5-cgi
$PHP_SCRIPT
RETVAL=$?
*)
echo "Usage: php-fastcgi {startstoprestart}"
exit 1
esac
exit $RETVAL Damos los permisos adecuados y añadimos php-fastcgi a los scripts de arranque y parada:
sudo chmod 755 /etc/init.d/php-fastcgi sudo chmod 755 /usr/bin/php-fastcgi sudo /usr/sbin/update-rc.d -f php-fastcgi defaults
Nos queda volver a editar el fichero de configuración de nginx, /usr/local/nginx/conf/nginx.conf, donde añadiremos, en la sección del servidor virtual que hemos creado, la configuración necesaria para que los scripts PHP sean redireccionados al proceso FastCGI. También en esta sección, deberemos cambiar la página de inicio de index.html a index.php y añadir una regla de reescritura para que WordPress funcione correctamente. Con todos estos cambios, la sección completa del servidor virtual de nginx para el blog quedaría:
server {
listen 80
server_name blog.midominio.com
access_log /var/log/nginx/blog.midominio.com/access.log
error_log /var/log/nginx/blog.midominio.com/error.log
location / {
root /var/www/blog.midominio.com
index index.php
if (-e $request_filename) {
break
}
rewrite ^/(.+)$ /index.php?q=$1 last
}
# 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/blog.midominio.com$fastcgi_script_name
include conf/fastcgi.conf
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html
location = /50x.html {
root html
}
} El fichero de configuración de FastCGI será /usr/local/nginx/conf/fastcgi.conf:
fastcgi_param QUERY_STRING $query_stringfastcgi_param REQUEST_METHOD $request_method fastcgi_param CONTENT_TYPE $content_type fastcgi_param CONTENT_LENGTH $content_length fastcgi_param SCRIPT_NAME $fastcgi_script_name fastcgi_param REQUEST_URI $request_uri fastcgi_param DOCUMENT_URI $document_uri fastcgi_param DOCUMENT_ROOT $document_root fastcgi_param SERVER_PROTOCOL $server_protocol fastcgi_param GATEWAY_INTERFACE CGI/1.1 fastcgi_param SERVER_SOFTWARE nginx fastcgi_param REMOTE_ADDR $remote_addr fastcgi_param REMOTE_PORT $remote_port fastcgi_param SERVER_ADDR $server_addr fastcgi_param SERVER_PORT $server_port fastcgi_param SERVER_NAME $server_name # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200
Para probar que funcionar, después de rearrancar nginx, podemos crear en /var/www/blog.midominio.com el siguiente fichero index.php:
<? phpinfo(); ?>
Si introducimos en el navegador la URL http://blog.midominio.com obtendremos una página con información sobre nuestra instalación de PHP.

![Validate my RSS feed [Valid RSS]](/wp-content/themes/javiervidal/images/valid-rss.png)
27 de Junio de 2008 a las 18:53
Hola!, me ha sido de gran ayuda tu articulo, tengo todo funcionando en su lugar :D,
nginx + php + rail , gracias!
5 de Octubre de 2008 a las 23:22
Hey Javier, muchas gracias por tu artículo! Me viene genial porque ahora uso nginx+mongrel pero estoy pensando meter también php para algunos dominios con phpbb y wordpress, y me daba pereza tener que cambiar a Apache. No sabía que se podía hacer con nginx…
Bueno, ahora tendré que decidir si cambiar a mod_rails o seguir un tiempo con mongrel.
12 de Abril de 2009 a las 1:09
Hola, interesante artículo. Pero me da curiosidad que no lo hayas instalado desde los repositorios oficiales de debian, ¿a que se debe?
Saludos
13 de Abril de 2009 a las 9:12
Si no recuerdo mal, la versión de nginx disponible en el repositorio de debian era bastante inferior a la última versión estable disponible de nginx.