Configuración del servidor web NGINX para la aplcación de Laravel

Instalación de NGINX dentro del contenidor

Una vez tenemos Laravel instalado en un contenedor, necesitamos configurar NGINX para que actua como servidor web frontal. Este servidor redirigirá las peticiones HTTP hacia el motor PHP-FPM que ejecuta Laravel.

1. Acceder al contenedor NGINX

Para comenzar con la configuración del servidor web, primero debemos introducir al contenedor donde se ejecutará NGINX. Ya tenemos un contenedor en ejecución llamado nginx, definido en el archivo docker-compose.yml.

Utilizamos el siguiente comando para acceder:

docker exec -it nginx sh

Explicación detallada del comando:

  • docker exec: permite ejecutar un comando dentro de un contenedor en funcionamiento.
  • -it: activa el modo interactivo y conecta nuestro terminal con la entrada estándar del contenedor.
  • nginx: es el nombre, una espécie de ID, del contenedor al que queremos acceder.
  • sh: es la shell predeterminada que se utiliza en los contenedores basados en Alpine Linux.

Una vez dentro, veremos que el prompt cambia para indicar que estamos dentro del contenedor.

Desde esta shell podemos ejecutar comandos como si estuviéramos dentro de un sistema Linux minimalista. Este entorno está aislado del sistema principal, y cualquier acción afectará exclusivamente a este contenedor.

Esta shell nos será útil para:

  • Instalar paquetes.
  • Crear y editar archivos de configuración.
  • Comprobar rutas de archivos, permisos y logs.
  • Ejecutar órdenes como nginx, cat, mkdir...

⚠️ Importante: si el contenedor nginx no está en ejecución, es necesario iniciarlo primero con docker start nginx, o crearlo si aún no existe.


2. Actualizar los repositorios e instalar NGINX y nano

Una vez dentro del contenedor, el siguiente paso es asegurarnos de que el sistema tiene acceso a la lista más actualizada de paquetes disponibles, y luego instalar el servidor NGINX con el editor de texto nano.

Ejecutamos los siguientes comandos:

apk update
apk add --no-cache nginx nano

Explicación detallada de cada comando:

  • apk update:
  • Este comando actualiza los índices de los paquetes disponibles en los repositorios del sistema.
  • Es equivalente a apt update en distribuciones basadas en Debian o yum update en RedHat/CentOS.
  • Es importante ejecutar este comando antes de instalar software para asegurarnos de que estamos descargando las versiones más recientes disponibles y no versiones obsoletas o no compatibles.

  • apk add --no-cache nginx nano:

  • apk add: se utiliza para instalar uno o más paquetes en Alpine Linux.
  • --no-cache: evita guardar archivos de índice temporalmente, lo que reduce el tamaño del contenedor. Es una práctica recomendada en contenedores para mantenerlos ligeros.
  • nginx: es el paquete del servidor web que vamos a configurar para servir la aplicación Laravel.
  • nano: es un editor de texto en terminal, sencillo pero potente, ideal para editar archivos de configuración como nginx.conf o archivos dentro de sites-available.

¿Por qué hacemos esto dentro del contenedor y no desde el sistema anfitrión?

Porque el contenedor NGINX está aislado del sistema principal, y cada contenedor necesita tener instaladas sus propias herramientas y servidores. Al instalar nginx dentro del contenedor, nos aseguramos de que todo el software necesario para servir la aplicación está incluido en su entorno de ejecución.


3. Crear directorios para la configuración de sitios web

En este paso vamos a organizar las configuraciones de los sitios web que NGINX servirá. Aunque Alpine Linux, y muchas imágenes ligeras de NGINX, no crean estos directorios por defecto, es una buena práctica establecer una estructura clara y mantenible.

Ejecutamos los siguientes comandos:

mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled

Explicación detallada de cada comando:

  • mkdir -p: crea un directorio. La opción -p asegura que no se generen errores si el directorio ya existe y también crea los directorios padres necesarios en caso de que no existan.
  • /etc/nginx/sites-available: es un directorio donde colocaremos todos los archivos de configuración de sitios disponibles. Aquí guardaremos las configuraciones de cada aplicación o dominio, pero no estarán activas aún.
  • /etc/nginx/sites-enabled: es donde colocaremos enlaces simbólicos a los archivos que están en sites-available para activar su uso real por parte de NGINX.

¿Por qué seguimos este esquema?

Este patrón proviene de distribuciones como Debian o Ubuntu, y facilita la administración de múltiples sitios en un mismo servidor. Al separar los sitios "disponibles" (archivos de configuración que existen pero no necesariamente están activos) de los "habilitados" (aquellos que sí se están usando actualmente), conseguimos:

  • Activar o desactivar sitios fácilmente sin eliminar su configuración.
  • Tener un entorno de configuración más limpio y mantenible.
  • Evitar errores accidentales que podrían surgir de modificar directamente la configuración principal de NGINX.

Ejemplo práctico de su utilidad:

Si queremos desactivar un sitio temporalmente, solo debemos eliminar el enlace simbólico correspondiente en sites-enabled, sin borrar su archivo original de configuración. Esto hace que trabajar con muchos sitios o entornos (producción, staging, pruebas) sea mucho más ágil y seguro.


4. Crear la configuración del sitio Laravel

En este paso vamos a crear un archivo de configuración específico para que NGINX pueda servir nuestra aplicación Laravel. Usaremos el editor nano para crear el archivo dentro del directorio sites-available.

nano /etc/nginx/sites-available/laravel.conf

Una vez abierto, pegamos el siguiente contenido:

server {
    listen 80;  # El servidor escuchará en el puerto 80, el puerto predeterminado para HTTP.

    server_name localhost;  # Define el nombre del servidor. En este caso, se acepta localhost.

    # Definimos el directorio raíz del proyecto Laravel donde se encuentra el archivo index.php
    root /var/www/html/laraview/public;

    index index.php index.html index.htm;  # Prioridad de archivos que se servirán si no se especifica un archivo concreto.

    # Habilitamos los logs de acceso y error, útiles para depuración y monitoreo.
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    # Configuramos cómo manejar las solicitudes HTTP
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        # Intenta servir el archivo directamente.
        # Si no existe, intenta con una carpeta.
        # Si tampoco existe, redirige la solicitud a index.php (comportamiento típico de Laravel).
    }

    # Configuración para manejar archivos PHP
    location ~ \.php$ {
        include fastcgi_params;  # Incluye parámetros necesarios para FastCGI.

        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        # Indica que las solicitudes PHP se enviarán al socket de PHP-FPM.

        fastcgi_param SCRIPT_FILENAME /laravel/pablo-app/public$fastcgi_script_name;
        # Define la ubicación del script PHP a ejecutar, combinando la ruta del proyecto con el archivo solicitado.
    }

    # Seguridad: denegar el acceso a archivos ocultos que comiencen con .ht (como .htaccess)
    location ~ /\.ht {
        deny all;
    }
}

Explicación destacada línea por línea del contenido laravel.conf:

  • server {}: define un bloque de servidor en NGINX, que agrupa la configuración de un sitio web.
  • listen 80;: indica que este servidor aceptará conexiones HTTP por el puerto 80.
  • server_name localhost;: define el nombre de dominio que será manejado por esta configuración. Aquí usamos localhost para desarrollo local.
  • root /var/www/html/laraview/public;: define la raíz del sitio. Laravel sirve sus páginas desde el directorio public, que contiene index.php.
  • index index.php index.html index.htm;: indica el orden de prioridad para servir archivos si se accede a un directorio.
  • error_log y access_log: especifican dónde se almacenarán los logs de errores y accesos, respectivamente. Son fundamentales para depurar problemas.
  • location /: bloque para manejar todas las solicitudes. El try_files intenta servir el archivo solicitado, y si no existe, reenvía la petición a index.php como lo requiere Laravel.
  • location ~ \.php$: bloque que se activa con solicitudes a archivos .php. Usa FastCGI para delegar la ejecución a PHP-FPM.
  • include fastcgi_params: carga parámetros estándar de FastCGI necesarios.
  • fastcgi_pass unix:/run/php/php8.4-fpm.sock;: indica el socket UNIX donde escucha PHP-FPM.
  • fastcgi_param SCRIPT_FILENAME: define la ruta física completa del script PHP a ejecutar.
  • location ~ /\.ht: deniega el acceso a archivos ocultos que puedan contener información sensible.

Con esta configuración, NGINX estará preparado para recibir peticiones HTTP y reenviarlas correctamente al backend PHP-FPM, permitiendo que Laravel responda adecuadamente a cada solicitud.


5. Activar el sitio Laravel

Una vez que hemos creado el archivo de configuración de Laravel dentro del directorio sites-available, necesitamos "activarlo" para que NGINX lo utilice al iniciar o recargar su configuración.

Para ello, creamos un enlace simbólico en el directorio sites-enabled, apuntando al archivo de configuración original:

ln -s /etc/nginx/sites-available/laravel.conf /etc/nginx/sites-enabled/

Explicación detallada del comando:

  • ln: comando para crear enlaces.
  • -s: crea un enlace simbólico (también conocido como acceso directo o alias).
  • /etc/nginx/sites-available/laravel.conf: es el archivo de configuración original del sitio Laravel.
  • /etc/nginx/sites-enabled/: es el lugar donde se colocan los archivos (o enlaces) que NGINX carga al iniciar.

¿Por qué crear un enlace simbólico y no copiar el archivo directamente?

Este enfoque modular permite:

  • Activar o desactivar sitios fácilmente sin modificar su archivo original. Si queremos desactivar Laravel, simplemente eliminamos el enlace simbólico de sites-enabled.
  • Evitar duplicación: todos los archivos de configuración están centralizados en sites-available, y los activamos a demanda.
  • Mantener orden: esta práctica es común en sistemas como Ubuntu/Debian y hace que la administración de múltiples sitios sea más clara.

6. Editar la configuración principal de NGINX

Después de crear y activar la configuración específica del sitio Laravel, necesitamos asegurarnos de que NGINX esté preparado para leer dicha configuración cuando se inicie o recargue.

Para lograrlo, debemos editar el archivo principal de configuración de NGINX:

nano /etc/nginx/nginx.conf

Este archivo contiene la configuración base del servidor web, incluyendo parámetros generales de rendimiento, rutas de logs, procesos worker, y lo más importante: el bloque http {} que agrupa las configuraciones de todos los sitios web que NGINX servirá.

Lo que debemos añadir o verificar:

Dentro del bloque http {}, debemos de asegurarnos de que existe la siguiente línea:

include /etc/nginx/sites-enabled/*;

¿Qué significa esta línea?

  • include: es una directiva de NGINX que permite incluir otros archivos de configuración.
  • /etc/nginx/sites-enabled/*: indica que todos los archivos dentro de este directorio (por ejemplo, laravel.conf) serán incluidos automáticamente como parte de la configuración del servidor.

¿Por qué es importante incluir esto?

  • Sin esta línea, NGINX ignorará completamente las configuraciones que hayamos activado en sites-enabled.
  • Es el puente que conecta las configuraciones por sitio con la configuración global.
  • Nos permite mantener una arquitectura modular, donde cada sitio tiene su propio archivo en lugar de meterlo todo en nginx.conf.

Con esto, hemos conectado correctamente la configuración modular del sitio Laravel a la configuración central de NGINX. A partir de ahora, cualquier archivo .conf ubicado y activado en sites-enabled/ será automáticamente gestionado por el servidor web.


7. Verificar la configuración de NGINX

Una vez que hemos realizado cambios en los archivos de configuración —ya sea en el archivo principal nginx.conf o en uno de los archivos de sitios como laravel.conf—, es fundamental verificar que no haya errores antes de reiniciar el servidor NGINX.

Para ello utilizamos el siguiente comando:

nginx -t

Explicación detallada del comando:

  • nginx: es el ejecutable principal del servidor web NGINX.
  • -t: esta opción le dice a NGINX que realice una prueba de configuración sin iniciar ni reiniciar el servidor.

Este comando no aplica los cambios, simplemente analiza todos los archivos de configuración para detectar errores de sintaxis, rutas mal escritas, parámetros inválidos o directivas ubicadas en secciones incorrectas.

¿Por qué es importante usarlo?

  • Previene fallos en producción: si reiniciamos NGINX con una configuración incorrecta, el servidor podría dejar de funcionar y provocar la caída del sitio web.
  • Evita confusión: al validar previamente, podemos estar seguros de que los archivos están bien escritos y son comprensibles para NGINX.
  • Facilita la depuración: si hay algún error, NGINX nos mostrará una descripción del problema y la ubicación exacta (línea y archivo).

Ejemplo de salida correcta:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Esto significa que la sintaxis es correcta y el servidor podrá cargar la configuración sin problemas.


8. Desactivar el sitio por defecto

Después de activar la configuración específica para Laravel, es recomendable desactivar el sitio por defecto que muchas instalaciones de NGINX incluyen de manera predeterminada.

Para hacerlo, eliminamos el enlace simbólico al archivo de configuración default dentro del directorio sites-enabled:

unlink /etc/nginx/sites-enabled/default

Explicación detallada del comando:

  • unlink: es un comando de Linux que elimina un archivo o un enlace simbólico.
  • /etc/nginx/sites-enabled/default: es la ruta habitual donde se encuentra el sitio por defecto habilitado.

¿Por qué debemos hacer esto?

  • El archivo default contiene una configuración genérica, normalmente orientada a mostrar una página de bienvenida de NGINX o servir contenido desde una ruta base como /usr/share/nginx/html.
  • Esta configuración puede entrar en conflicto con nuestrio sitio Laravel, especialmente si ambos están configurados para escuchar en el mismo puerto (listen 80;) o responder al mismo nombre de servidor (server_name localhost;).
  • Al mantener el sitio por defecto activo junto con Laravel, NGINX puede mostrar errores, comportamientos inesperados o simplemente servir el contenido equivocado.

9. Reiniciar NGINX

Después de realizar todos los cambios en los archivos de configuración de NGINX —ya sea el archivo principal, los sitios disponibles o activados—, es necesario aplicar esos cambios reiniciando o recargando el servidor NGINX.

Este es el ciclo de vida del servicio NGINX desde la línea de comandos:

nginx
nginx -s stop
nginx -s reload

Explicación detallada de cada comando:


nginx

  • Este comando lanza el servidor NGINX si aún no está en funcionamiento.
  • Se utiliza normalmente al iniciar manualmente el servicio por primera vez dentro de un contenedor o sistema.
  • Si ya hay una instancia en ejecución, es posible que este comando no tenga efecto o devuelva un error como "nginx: [emerg] bind() to 0.0.0.0:80 failed".

nginx -s stop

  • Esta opción detiene el servidor NGINX de forma inmediata.
  • Libera los puertos en uso (como el 80) y finaliza todos los procesos del servicio.
  • Es útil cuando necesitas reiniciar completamente el servicio o detenerlo por mantenimiento.

nginx -s reload

  • Esta es la forma recomendada de aplicar cambios en la configuración sin interrumpir el servicio.
  • Recarga los archivos de configuración modificados (nginx.conf, laravel.conf, etc.) sin necesidad de detener NGINX ni cerrar conexiones activas.
  • Es ideal para entornos en producción porque permite hacer ajustes sin generar tiempo de inactividad.

Con todos estos passos, NGINX estará completamente configurado per servir nuestra aplicación Laravel utilizando PHP-FPM como motor de ejecución.