Be a happy coder

You are here

Instalar Nginx para Drupal 6 en Debian

06 Feb 2012

Nginx es un servidor web ligero y muy eficiente. Por supuesto Apache es un gran servidor web, con multitud de módulos y soporte para prácticamente cualquier cosa, y es un servidor con el que llevo varios años trabajando. Sin embargo, la potencia que me ha demostrado nginx y sobretodo el mínimo consumo de recursos que necesita para obtener ese rendimiento, me han convencido para mostraros como pasar a utilizarlo como vuestro servidor web habitual.

nginx

Nginx

Nginx tiene un desarrollo muy activo y cada pocas semanas suele salir una nueva versión. Sin embargo, si no te sientes cómodo con una versión reciente y poco comprobada por la comunidad, puedes utilizar los paquetes de la distribución. De modo que ejecutamos

sudo aptitude install nginx

Con esto ya tenemos disponible nginx en nuestro sistema. Así de simple :)

La estructura de ficheros de configuración reside en /etc/nginx. El fichero nginx.conf contiene la configuración principal, que veremos con más detalle a continuación. A partir de él se cargarán otras configuraciones, que se pueden colocar en la carpeta /etc/nginx/conf.d y/o los vhosts que definamos (dentro de la carpeta sites-enabled).

PHP-FPM

Bien, antes decía que ya teníamos instalado nginx, pero necesitaremos algo más ;) y es la posibilidad de poder procesar PHP. Nginx soporta perfectamente el protocolo FastCGI, a diferencia de Apache que tiene un soporte parcial mediante el módulo mod_fcgid. FastCGI permite reducir la carga de la interconexión del servidor web, permitiéndole a un servidor atender más peticiones a la vez. Esta separación permite a los procesos del servidor y de las aplicaciones ser reiniciados en forma independiente; una consideración importante a tomar en cuenta en sitios web muy ocupados.

Si no has utilizado antes PHP-FPM, probablemente te opongas a seguir usando los antiguos métodos con spawn-fcgi o php-cgi. A partir de PHP 5.3.3, PHP-FPM está incluido como parte de PHP sin embargo para Squeeze no está disponible el paquete (al menos en stable, puesto que para testing si lo tenemos). Para debian lenny/squeeze el repositorio dotdeb nos proporciona el paquete php5-fpm.

Modificamos nuestro fichero /etc/apt/sources.list y añadimos el repositorio de dotdeb:

  • Squeeze :
    deb http://packages.dotdeb.org stable all
    deb-src http://packages.dotdeb.org stable all
  • Lenny :
    deb http://packages.dotdeb.org oldstable all
    deb-src http://packages.dotdeb.org oldstable all

Después obtenemos la clave GnuPG apropiada:

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -

Actualizamos los paquetes disponibles y localizamos el paquete para php-fpm:

japicoder@endor:~$ sudo aptitude update
[ ... ]
japicoder@endor:~$ sudo aptitude search php5-fpm
p   php5-fpm                                                                         - server-side, HTML-embedded scripting language (FPM-CGI binary)

Debido a que tengo los módulos de la distribución squeeze de debian (stable), intentar instalar este paquete me implica sustituir todos los otros que tenga instalados

japicoder@endor:~$ sudo aptitude install php5-fpm
     Actualizar los paquetes siguientes:                                                 
1)     libapache2-mod-php5 [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]
2)     php5-cli [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]          
3)     php5-common [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]       
4)     php5-curl [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]         
5)     php5-gd [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]           
6)     php5-imap [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]         
7)     php5-mcrypt [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]       
8)     php5-mysql [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]        
9)     php5-sybase [5.3.3-7+squeeze3 (now, stable) -> 5.3.10-1~dotdeb.1 (<NULL>)]

Tras la instalación, tenemos que se ha instalado como demonio, respondiendo en 127.0.0.1:9000. Prefiero utilizar los socket Unix, para evitar la sobrecarga TCP e incrementa la seguridad ya que los permisos basados en ficheros son bastante fuertes. Modificamos el fichero /etc/php5/fpm/pool.d/www.conf, para utilizar un socket:

;listen = 127.0.0.1:9000
listen = /tmp/php5-fpm.sock

y descomentamos las líneas de listen.owner, listen.group, listen.mode.

Nota de seguridad: En /etc/php5/fpm/php.ini, establecer cgi.fix_pathinfo a 0 para utilizar Nginx con PHP-FPM/FastCGI, de otra forma, algo tan simple como /forum/avatars/user2.jpg/index.php podría ser utilizado para ejecutar un php subido como un script oculto en una imagen.

Reiniciamos el demonio para que empiece a utilizar el socket:

sudo invoke-rc.d php5-fpm restart

Configuración

Vamos a configurar fpm para nginx. Creamos un fichero con la configuración que necesitamos para después incluirla en nuestros vhosts:

root@endor:/etc/nginx# cp fastcgi_params php-fpm.conf

Le ponemos este contenido:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_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  SCRIPT_FILENAME    $document_root$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/$nginx_version;

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;

Ahora preparamos un fichero para el vhost de una instalación con drupal 6. Lo ubicamos en /etc/nginx/sites-available y lo enlazamos a sites-enabled:

server {

        listen   80;

        server_name  server.com www.server.com;

        root /var/www/vhosts/server.com/httpdocs;
        index  index.php;

        access_log  /var/log/nginx/server.access.log;
        error_log  /var/log/nginx/server.error.log;

#        auth_basic  "Introduce tu acceso";
#        auth_basic_user_file    /var/www/.htpasswd;

        # -- Reglas de denegación
        # No permitir acceso a ficheros ocultos del sistema, los que comienzan con punto
        location ~ /\. {
                access_log off;
                log_not_found off;
                deny all; 
        }

        # Tampoco permitir acceso desde fuera
        location ~* \.(txt|log)$ {
                #allow 192.168.0.0/16;
                deny all;
        }

        location ~ \..*/.*\.php$ { return 403; }

        # Evitar estos ficheros en las peticiones
        location ~* (/\..*|settings\.php$|\.(?:git|htaccess|engine|inc|info|install|module|profile|pl|po|sh|.*sql|theme|tpl(?:\.php)?|xtmpl)$|^(?:Entries.*|Repository|Root|Tag|Template))$ {
                return 444;
        }

        # -- Configuraciones genéricas para drupal
        location / {
                try_files $uri @rewrite;
        }

        # url limpias para SEO
        location @rewrite {
                rewrite ^/(.*)$ /index.php?q=$1 last;
        }

        # Imagenes con imagecache
        location ~ ^/sites/.*/files/imagecache/ {
                # simple y fácil: si la imagen no existe, utiliza index.php para generarla!
                try_files $uri @rewrite;
        }

        # servir ficheros estáticos directamente 
        location ~* \.(?:ico|gif|jpe?g|png|css|js)$ {
                expires max;
                add_header Pragma public;
                add_header Cache-Control "public, must-revalidate, proxy-revalidate";
                log_not_found off;
        }

        # procesar the PHP scripts via FastCGI
        location ~ .php$ {
                try_files $uri @rewrite;    # Comprobar que el php existe
                include php-fpm.conf;
                fastcgi_read_timeout 240;
                fastcgi_pass unix:/tmp/php5-fpm.sock;
        }
}

Reiniciamos nginx para tener disponible el vhost y listo

invoke-rc.d nginx restart

Mi recomendación es instalar además alguna caché op-code como APC.

Referencias

http://wiki.nginx.org/ como guía sobre las opciones disponibles.

Nginx: An Introduction to the Nginx Configuration File | Martin Fjordvald un magnífico blog en el que he visto artículos interesantes sobre Nginx.

Etiquetas: