Nginx: multiples aplicaciones web en subdirectorios con un solo dominio

En algunos casos, cuando necesitamos servir múltiples aplicaciones web a través de un único dominio principal con Nginx lo hacemos utilizando subdominios apuntados a distintos directorios o servidores, pero cuando queremos servirlos utilizando subdirectorios apuntados a distintos directorios a través de un único dominio principal y con aplicaciones escritas en distintos lenguajes es necesario seguir una serie de pasos explicados en este pequeño tutorial utilizando como distribución CentOS 6.4 64bit, aunque debería funcionar para otras distribuciones de GNU/Linux, y con Nginx en su versión 1.5.1,

Primero dejemos claro que los directorios que utilizaremos como ejemplo son:

  • Para el dominio principal (tudominio.com) utilizaremos el directorio /home/user/public_html, contendrá solamente archivos .js , .html , .css e imagenes.
  • Para una primera aplicación web escrita en PHP utilizaremos el dominio con la ruta tudominio.com/webapp01-php/ apuntado al directorio /home/user/webapp01-php/
  • Para una segunda aplicación web escrita también en PHP utilizaremos el dominio con la ruta tudominio.com/webapp02-php/ apuntado al directorio /home/user/webapp02-php/
  • Para una tercera aplicacion web escrita Javascript utlizando como servidor "NodeJS" utilizaremos el dominio con la ruta tudominio.com/webapp-nodejs/ apuntado al directorio /home/user/webapp-nodejs/

Segundo, se debe contar con las versiones mas recientes instaladas de php y php-fpm. Si vas a compilar e instalar Nginx 1.5 desde las fuentes puedes seguir este pequeño tutorial que realice en el que se explican todos los detalles de su instalación en CentOS 6.4.

Configurando Nginx

En Nginx se le llama bloque a cada directiva que inicia y termina con { } , así pues http{ } es la primera directiva que vamos a usar y proporciona el contexto para especificar las directivas relacionadas con el servidor HTTP. Para poder utilizar subdirectorios apuntados a distintos directorios a través de un dominio principal y con aplicaciones escritas en distintos lenguajes es necesario usar las directivas location que establece la configuración en función de una solicitud uri y alias que permite definir un reemplazo para una ubicación especificada. Vamos a configurar nuestro dominio principal apuntado al directorio /home/user/public_html, esto lo hacemos generando nuestro bloque server {} que va contenido dentro del bloque http {} en el archivo de configuración ubicado en /etc/nginx/nginx.conf,  quedaría algo como lo siguiente:

server {
    ##Puerto de escucha
    listen 80;

    ##Dominio principal
    server_name tudominio.com;
    server_tokens off;
    charset utf-8;
    index index.php index.html index.htm;

    error_log /var/log/nginx/tudominio.error.log debug;
    access_log /var/log/nginx/tudominio.access.log main;

    ##Ruta del dominio principal: tudominio.com
    location / {
        root /home/user/public_html
        autoindex on;
    }
 }

De esta forma al ingresar a nuestro tudominio.com mostraremos los archivos que esten en el directorio /home/user/public_html. Configuraremos ahora nuestra primera aplicación escrita en php, utilizaremos las directivas location y alias, nuestro archivo quedaría algo como lo siguiente:

##Primera aplicacion web escrita en php: tudominio.com/webapp01-php
location /webapp01-php {
#Alias al directorio que contienen los archivos en .php
        alias /home/user/webapp01-php;
        autoindex on;
        
        ##Uso de la directiva location para que tome todos los archivos .php
        ##y los sirva utilizando php-fpm
        location ~ /webapp01-php/.+\.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            allow 127.0.0.1;
            fastcgi_index index.php;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
}


Con la configuración anterior cuando ingresamos al dominio con subdirectorios tudominio.com/webapp01-php veremos todos los archivos escritos en .php que se encuentran en la ruta /home/user/webapp01-php. Ahora configuraremos la segunda aplicación escrita en .php:

##Segunda aplicacion web escrita en php: tudominio.com/webapp02-php
location /webapp02-php {
        #Alias al directorio que contienen los archivos en .php
        alias /home/user/webapp02-php;
        try_files $uri $uri/ /index.php?q=$uri&$args
        autoindex off;

        location ~ /webapp02-php/.+\.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            allow 127.0.0.1;
            fastcgi_index index.php;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
}

Por ultimo, configuraremos una tercer aplicación web escrita en javascript utilizando como servidor NodeJS, la misma ya debería estar corriendo y en escucha por el puerto 3000, nuestro archivo final se vería como el siguiente:

server {
    ##Puerto de escucha
    listen 80;

    ##Dominio principal
    server_name tudominio.com;
    server_tokens off;
    charset utf-8;
    index index.php index.html index.htm;

    error_log /var/log/nginx/tudominio.error.log debug;
    access_log /var/log/nginx/tudominio.access.log main;

    ##Ruta del dominio principal: tudominio.com
    location / {
        root /home/user/public_html
        autoindex on;
    }
    ##Primera aplicacion web escrita en php: tudominio.com/webapp01-php
    location /webapp01-php {
        #Alias al directorio que contienen los archivos en .php
        alias /home/user/webapp01-php;
        autoindex off;
        
        ##Uso de la directiva location para que tome todos los archivos .php
        ##y los sirva utilizando php-fpm
        location ~ /webapp01-php/.+\.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            allow 127.0.0.1;
            fastcgi_index index.php;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
    }
    
    ##Segunda aplicacion web escrita en php: tudominio.com/webapp02-php
    location /webapp02-php {
        #Alias al directorio que contienen los archivos en .php
        alias /home/user/webapp02-php;
        try_files $uri $uri/ /index.php?q=$uri&$args
        autoindex off;

        location ~ /webapp02-php/.+\.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            allow 127.0.0.1;
            fastcgi_index index.php;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
    }
    ##Tercera aplicacion web escrita en .js : tudominio.com/webapp-nodejs
    location /webapp-nodejs {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://127.0.0.1:3000;
        proxy_redirect off;
    }
 }

Deberán tener correctamente configurado php-fpm.conf para que no le genere errores, en algunos casos, ciertos problemas se corrigen cambiado los permisos adecuados a los directorios así como también estableciendo el grupo de usuarios en el directorio con el que se ha iniciado y configurado php-fpm. Pueden echarle un ojo en Github.com al archivo de configuración que uso para php-fpm y un .conf que tengo con un ejemplo para servir Drupal y una aplicación php. ¿Cualquier duda? comenta!