19 noviembre 2007

Cómo instalar Nginx para sustituir a Apache, primera parte

Primera parte, Segunda parte, Tercera parte, Cuarta parte

Hasta hace poco tiempo estábamos utilizando apache en todos nuestros servidores para servir páginas web. Nuestros servidores tienen un gran componente estático y un pequeño componente dinámico mediante php. El gran problema que nos planteaba apache es que nuestras páginas sirven varios cientos de miles de páginas diarias, y en momentos de gran tráfico las máquinas estaban al borde del bloqueo, debido a que los procesos de apache ocupan la misma cantidad de memoria independientemente de que la página servida sea estática o dinámica. Por esa misma razón no podíamos activar el keepalive de apache generándose un nuevo proceso con cada petición.

Buscando una solución encontramos varios servidores ligeros optimizados páginas estáticas que podían servir páginas dinámicas activando la extensión FastCGI.
Probamos lighttpd, cherokee y nginx. De todos ellos finalmente nos quedamos con enginex.

Aquí vamos a mostrar cómo instalar nginx con FastCGI en un servidor que no tiene conexión a base de datos, pero en el caso de necesitar conexión a base de datos la instalación es exactamente igual, simplemente hay que añadir en la compilación de php el flag "--with-mysql", (o lo que sea pertinente en el caso de utilizar otro sistema de bases de datos).

La instalación se hace en tres pasos, primero la instalación de php, segundo la instalación de nginx, y tercero la configuración y conectar nginx con php.

1.- Instalación de php

Decidimos compilar php para no interferir con la instalación que pudiera tener el sistema, de ese modo, si algo fuera mal, siempre podemos volver atrás, levantar apache y seguir funcionando como lo estuviéramos haciendo hasta estos momentos.

  • Descargamos la última versión de php en un directorio, en nuestro caso elegimos /usr/local/src:
root@one src]# wget "http://es2.php.net/get/php-5.2.5.tar.gz/from/this/mirror"


  • Descomprimimos, cambiamos el propietario del nuevo directorio al usuario sin privilegios que elijamos, hacemos su a ese usuario.
[root@one src]# tar xvfz php-5.2.5.tar.gz
[root@one src]# chown -R jose:jose php-5.2.5
[root@one src]# cd php-5.2.5
[root@one php-5.2.5]# su jose

  • Compilamos
[jose@one php-5.2.5]$ ./configure --prefix=/opt/php --with-gd --enable-fastcgi --enable-sysvsem --enable-sysvshm


--prefix es el directorio donde queremos que se instale.
--enable-fastcgi para que genere el fichero con soprote para fastcgi
--enable-sysvsem para que tenga las funciones de php deacceso a semáforos.
--enable-sysvshm para que tenga las funciones de php de acceso a la memoria compartida.
[jose@one php-5.2.5]$ make
[jose@one php-5.2.5]$ make test


Si el test sale correcto, o simplemente nos muestra algún pequeño bug de cosas que probablemente nosotros no vamos a utilizar podemos pasar a compilar.

[jose@one php-5.2.5]$ exit
[root@one php-5.2.5]# make install

(He hecho la misma instalación en un fichero en el que tenemos un captcha y no funcionaba, aquí la aclaración).

Ya tenemos el fichero instalado

2.- Instalación de nginx

  • Descargamos la última versión en un directorio, de nuevo elegimos /usr/local/src:
[root@one src]# wget http://sysoev.ru/nginx/nginx-0.5.33.tar.gz


  • Descomprimimos, cambiamos el propietario del nuevo directorio al usuario sin privilegios que elijamos, hacemos su a ese usuario.
[root@one src]# tar xvfz nginx-0.5.33.tar.gz
[root@one src]# chown -R jose:jose nginx-0.5.33
[root@one src]# cd nginx-0.5.33
[root@one src]# su jose


  • Compilamos
[jose@one nginx-0.5.33]$ ./configure --with-http_stub_status_module
[jose@one nginx-0.5.33]$ make
[jose@one nginx-0.5.33]$ exit
[root@blubbster nginx-0.5.33]# make install


El stub_status es un módulo para ver las visitas, keepalive, etc,... similar al status de apache aunque con menos funcionalidades.

No le hemos puesto parámetros de compilación de debug, ni hemos cambiado el prefix, por lo cual el directorio por defecto es /usr/local/nginx/ .

Aquí los directorios más importantes que tenemos son el directorio conf donde se situan los directorios de configuración y el directorio sbin donde está el binario de nginx. El fichero de configuración principal que tenemos es el nginx.conf.

3.- Conexión nginx con php mediante FastCGI


Hay dos maneras de activar el servidor fastcgi:
  • Ejecutar el servidor FastCGI que se ha compilado con php - este método no requiere de software de terceros.
  • Ejecutar PHP con software de terceros. Este método es más cómodo que el primero porque tiene más flexibilidad.
En nuestro caso hemos elegido el segundo método por que es más fácil levantar el servidor simplemente con un comando. Para ello necesitamos el programa spawn-fcgi de lighttpd, si no queremos complicarnos la vida basta con instalar el lighttpd en un directorio que no moleste. Lo único que vamos a utilizar de esta instalación es el spawn-fcgi.
De este modo ejecutamos la siguiente línea:

/usr/local/lighttpd/bin/spawn-fcgi -f /opt/php/bin/php-cgi -s /tmp/fcgi.sock -u apache -C 25



-f para indicar el binario de php compilado con soporte cgi
-s para indicar la conexión por sockets (también se puede conectar por ip)
-u para indicar el usuario que va a correr el servidor FastCGI
-C para indicar el número de instancias de FastCGI que vamos a abrir

Tenemos que editar el fichero de configuración de nginx y indicar cómo vamos a acceder a FastCGI.

En nuestro caso ésta es la configuración que tenemos:

location ~ \.php$|\.htm$ {
#fastcgi_pass localhost:10005;
fastcgi_pass unix:/tmp/nginx-fcgi;
fastcgi_index index.htm;
fastcgi_param SCRIPT_FILENAME /var/www/html/blubster.com$fastcgi_script_name;
fastcgi_intercept_errors on;
#include /usr/local/nginx/conf/fastcgi.conf;
}




Después de cambiar el fichero de configuración de nginx ya podríamos arrancar el servidor para ver qué todo funciona correctamente.
En otro post profundizaré un poco en la configuración y comandos de nginx

Primera parte, Segunda parte, Tercera parte, Cuarta parte

6 comentarios:

Antonio dijo...

hola

en el punto 3 indicas: "Ejecutar el servidor FastCGI que se ha compilado con php...", puedes poner un ejemplo de como seria, ya que he estado buscando por internet y no he encontrado nada. muchas gracias

saludos

josé dijo...

Más o menos hay que arrancar el fastcgi a manija. Este es un script de bash para arrancarlo, ahora no me acuerdo, pero creo que hay que modificar algo para que funcione:

#!/bin/bash

## ABSOLUTE path to the PHP binary
PHPFCGI="/opt/php/bin/php"

## tcp-port to bind on
FCGIPORT="8888"

## IP to bind on
FCGIADDR="127.0.0.1"

## number of PHP children to spawn
PHP_FCGI_CHILDREN=5

## number of request before php-process will be restarted
PHP_FCGI_MAX_REQUESTS=1000

# allowed environment variables sperated by spaces
ALLOWED_ENV="ORACLE_HOME PATH USER"

## if this script is run as root switch to the following user
USERID=www-data

################## no config below this line

if test x$PHP_FCGI_CHILDREN = x; then
PHP_FCGI_CHILDREN=5
fi

ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN"
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS"
ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS"

if test x$UID = x0; then
EX="/bin/su -m -c \"$PHPFCGI -q -b $FCGIADDR:$FCGIPORT\" $USERID"
else
EX="$PHPFCGI -b $FCGIADDR:$FCGIPORT"
fi

echo $EX

# copy the allowed environment variables
E=

for i in $ALLOWED_ENV; do
E="$E $i=${!i}"
done

# clean environment and set up a new one
nohup env - $E sh -c "$EX" &> /dev/null &



Para nginx es exactamente igual

Saludos

maelse dijo...

Hola José, estoy intentado seguir tu tutorial para sustituir Apache con Nginx pero en la línea "./configure --with-http_stub_status_module" la consola me devuelve el siguiente error:

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre= option.

Estoy utilizando Centos 5 y Apache instalado con cPanel&WHM.

Saludos.

Jose dijo...

Eso simplemente es que, o bien no existe la librería pcre, o bien no la encuentra. Hay varios rpms en centos, como pueden ser estos:


pcre-devel-6.6-2.el5_1.7
pcre-6.6-2.el5_1.7

Pero nginx te da la opción de compilarla también estáticamente, es decir dentro del paquete, incluyendo la opción --with-pcre en el configure.

En resumen, o instalas la librería con el yum, o pides a nginx que la compile, pero de este modo sólo va a estar disponible para nginx.

maelse dijo...

Hola gracias José, solucione lo del RPM(pcre-devel-6.6-2.el5_1.7).
Ahora después de ejecutar make en el punto de "Copilamos" obtengo la siguiente salida de la consola:
"objs/ngx_modules.o \
-lcrypt -lpcre -lcrypto -lz
objs/src/os/unix/ngx_process.o: In function `ngx_process_get_status':
/srv/nginx-0.8.54/src/os/unix/ngx_process.c:490: warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
/srv/nginx-0.8.54/src/os/unix/ngx_process.c:490: warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
make[1]: Leaving directory `/srv/nginx-0.8.54'"

Creo que esta mal pero no se a que es debido. Voy a continuar a ver a donde llego......

Jose dijo...

Pero eso parece sólo un warning. ¿No te llega a instalar?.

A ver si tengo tiempo uno de estos días y me pongo una máquina virtual con centos, pero te debería funcionar. Eso es un warning de utilización de otra función....

Dime si te llega a funcionar