LEMP Stack

Implantación de Aplicaciones Web

José Juan Sánchez Hernández

Curso 2023/2024



1 LEMP Stack

En esta práctica vamos a instalar la pila LEMP que es una variación de la pila LAMP. La única diferencia es que usa el servidor Nginx en lugar de Apache.

Nginx está considerado como un servidor web ligero de alto rendimiento que además suele ser utilizado como proxy inverso y balanceador de carga.

1.1 Instalación del servidor web Nginx

sudo apt update
sudo apt install nginx -y

1.2 Instalación de php-fpm y php-mysql

1.2.1 php-fpm

El paquete php-fpm (PHP FastCGI Process Manager) es una implementación alternativa al PHP FastCGI con algunas características adicionales útiles para sitios web com mucho tráfico.

El uso de PHP-FPM (PHP FastCGI Process Manager) con Nginx es ideal porque permite mejorar el consumo de memoria del servidor, haciendo que el servidor tenga un bajo consumo de recursos, mejorando de esta manera su rendimiento y escalabilidad. PHP-FPM se ejecutará como un servicio independiente de Nginx que se va a encargar de interpretar las peticiones que incluyen código PHP que reciba el servidor Nginx. Cuando el servidor Nginx reciba una petición HTTP donde haya que procesar código PHP, el servidor Nginx se comunicará con PHP-FPM a través de un socket UNIX o un socket TCP/IP para recibir la respuesta del código PHP interpretado y servirla al cliente que realizó la petición.

sudo apt install php-fpm -y

1.2.2 php-mysql

El paquete php-mysql permite a PHP interaccionar con el sistema gestor de bases de datos MySQL.

sudo apt install php-mysql -y

1.3 Configuración de Nginx para comunicarse con php-fpm a través de un socket UNIX

Los sockets UNIX nos permiten realizar comunicación entre procesos, también conocida como IPC (Inter-Process Communication)), que es una función básica de los sistemas operativos que permite el intercambio de datos entre procesos de una forma eficiente. Sin embargo, los sockets TCP/IP nos permiten comunicar procesos a través de una red.

Un sockets UNIX es un tipo de archivo especial, donde los procesos pueden escribir y leer datos para comunicarse.

Los sockets UNIX tienen la ventaja que permiten realizar comunicaciones más rápidas entre los procesos, pero tienen el inconveniente de que son menos escalables que los sockets TCP/IP porque sólo permiten comunicar procesos que se están ejecutando en el mismo sistema operativo de la misma máquina.

En esta sección vamos a explicar cómo podemos configurar Nginx para que pueda comunicarse con el proceso php-fpm a través de un socket UNIX.

Editamos el archivo de configuración /etc/nginx/sites-available/default:

sudo nano /etc/nginx/sites-available/default

Realizamos los siguientes cambios:

Un posible archivo de configuración para el servidor podría ser el siguiente:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.php index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        location ~ /\.ht {
                deny all;
        }
}

Nota: En el momento de redactar esta guía la versión de PHP es la 8.1. Tenga en cuenta que esta versión puede cambiar en un futuro.

Podemos comprobar que la sintaxis del archivo de configuración es correcta con el comando:

sudo nginx -t

Una vez realizados los cambios reiniciamos el servicio nginx:

sudo systemctl restart nginx

1.4 Comprobar que la instalación se ha realizado correctamente

Crea un archivo llamado info.php en el directorio /var/www/html.

sudo nano /var/www/html/info.php

Añade el siguiente contenido:

<?php

phpinfo();

?>

Ahora accede desde un navegador a la URL: http://IP/info.php, donde IP será la dirección IP de su máquina virtual. Por ejemplo, si la dirección IP de su máquina virtual es 192.168.22.200, la URL será: http://192.168.22.200/info.php

1.5 Configuración de Nginx para comunicarse con php-fpm a través de un socket TCP/IP

Los sockets TCP/IP nos permiten comunicar procesos que se pueden estar ejecutando en la misma máquina o en máquinas diferentes, a través de una red.

1.5.1 Opción 1: Nginx y php-fpm se ejecutan en la misma máquina

1.5.1.1 Configuración de php-fmp

En primer lugar hay que modificar la directiva listen del archivo /etc/php/8.1/fpm/pool.d/www.conf.

sudo nano /etc/php/8.1/fpm/pool.d/www.conf

Si buscamos la directiva listen en el archivo de configuración nos encontramos que en la configuración por defecto está escuchando en el socket UNIX /run/php/php8.1-fpm.sock. A continuación se muestra un fragmento del archivo de configuración por defecto que hace referencia a la directiva listen.

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php/php8.1-fpm.sock

Habrá que modificar la directiva listen por la dirección de localhost (127.0.0.1) y un puerto. En este ejemplo utilizaremos el puerto 9000. La directiva listen quedaría así:

listen = 127.0.0.1:9000

Una vez que hemos realizado las modificaciones en la configuración reiniciamos el servicio de php-fpm para que se apliquen los cambios:

sudo systemctl restart php8.1-fpm

1.5.1.2 Configuración de Nginx

En este caso hay que configurar en el archivo /etc/nginx/sites-available/default que los scripts PHP se van a enviar al servidor FastCGI a través de un socket TCP/IP.

sudo nano /etc/nginx/sites-available/default

Habrá que modificar la directiva de configuración fastcgi_pass para indicar la dirección y el puerto donde se encuentra el servidor FastCGI. Por ejemplo, si el servidor FastCGI se está ejecutando en la misma máquina (127.0.0.1), en el puerto 9000 habrá que asignarle el siguiente valor:

fastcgi_pass 127.0.0.1:9000;

Un posible archivo de configuración para el servidor podría ser el siguiente:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.php index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                # With php-cgi (or other tcp sockets):
                fastcgi_pass 127.0.0.1:9000;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        location ~ /\.ht {
                deny all;
        }
}

Podemos comprobar que la sintaxis del archivo de configuración es correcta con el comando:

sudo nginx -t

Una vez realizados los cambios reiniciamos el servicio nginx:

sudo systemctl restart nginx

1.5.2 Opción 2: Nginx y php-fpm se ejecutan diferentes máquinas

Al utilizar diferentes máquinas para el servidor web Nginx y php-fpm, debemos buscar una solución para compartir los archivos de contenido estático y el código fuente de la aplicación web, entre las dos máquinas.

Algunas de las soluciones que podemos utilizar para compartir el contenido entre los dos servidores son las siguientes:

1.6 Configuración de la directiva cgi.fix_pathinfo para mejorar la seguridad

Es recomendable realizar un cambio en la directiva de configuración cgi.fix_pathinfo por cuestiones de seguridad. Editamos el siguiente archivo de configuración:

sudo nano /etc/php/8.1/fpm/php.ini

Nota: En el momento de redactar esta guía la versión de PHP es la 8.1. Tenga en cuenta que esta versión puede cambiar en un futuro.

Buscamos la directiva de configuración cgi.fix_pathinfo que por defecto aparece comentada con un punto y coma y con un valor igual a 1.

;cgi.fix_pathinfo=1

Eliminamos el punto y coma y la configuramos con un valor igual a 0.

cgi.fix_pathinfo=0

Una vez modificado el archivo de configuración y guardados los cambios reiniciamos el servicio php8.1-fpm.

sudo systemctl restart php8.1-fpm

Referencias sobre los problemas de seguridad relacionados con la directiva cgi.fix_pathinfo:

2 Referencias

3 Licencia

Licencia de Creative Commons
Esta página forma parte del curso Implantación de Aplicaciones Web de José Juan Sánchez Hernández y su contenido se distribuye bajo una licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional.