Cómo instalar y configurar Nginx en Linux paso a paso

Nginx es uno de los servidores web más utilizados en entornos Linux. Puede utilizarse para alojar páginas web, actuar como proxy inverso, distribuir tráfico entre varios servidores o gestionar conexiones HTTPS.

Su arquitectura orientada a eventos permite atender una gran cantidad de conexiones simultáneas utilizando relativamente pocos recursos, por lo que es una opción muy habitual tanto para pequeños servidores VPS como para infraestructuras de mayor tamaño.

En este tutorial veremos cómo instalar Nginx, publicar nuestro primer sitio web, configurar el firewall y aplicar algunos ajustes básicos de rendimiento y seguridad.


Requisitos

Antes de comenzar necesitaremos:

  • Un servidor Linux.
  • Acceso mediante SSH.
  • Usuario root o permisos sudo.
  • Conexión a Internet.
  • Los puertos 80 y 443 disponibles.
  • Opcionalmente, un dominio apuntando hacia la IP del servidor.

Los ejemplos principales están pensados para Ubuntu y Debian, aunque también veremos la instalación en distribuciones basadas en RHEL.


1. Instalar Nginx en Ubuntu o Debian

Primero actualizamos la información de los repositorios:

sudo apt update

También podemos actualizar los paquetes instalados:

sudo apt upgrade -y

Ahora instalamos Nginx:

sudo apt install nginx -y

Una vez terminado el proceso podemos comprobar qué versión tenemos instalada:

nginx -v

2. Iniciar Nginx automáticamente

Normalmente el servicio se inicia durante la instalación, pero podemos asegurarnos ejecutando:

sudo systemctl start nginx

Para que arranque automáticamente cuando reiniciemos el servidor:

sudo systemctl enable nginx

Podemos consultar su estado con:

sudo systemctl status nginx

Si todo funciona correctamente debería aparecer:

active (running)

3. Instalar Nginx en Rocky Linux, AlmaLinux o CentOS

En distribuciones modernas basadas en RHEL podemos utilizar dnf.

Actualizamos el sistema:

sudo dnf update -y

Instalamos Nginx:

sudo dnf install nginx -y

Después iniciamos el servicio:

sudo systemctl start nginx
sudo systemctl enable nginx

Y comprobamos su estado:

sudo systemctl status nginx

En instalaciones antiguas de CentOS puede utilizarse yum en lugar de dnf.


4. Abrir los puertos HTTP y HTTPS

Para acceder al servidor web desde Internet tendremos que permitir tráfico hacia los puertos:

  • 80/TCP: HTTP.
  • 443/TCP: HTTPS.

Ubuntu y Debian con UFW

Podemos autorizar ambos protocolos con:

sudo ufw allow 'Nginx Full'

Otra opción es abrir individualmente los puertos:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Para consultar las reglas:

sudo ufw status

Rocky Linux, AlmaLinux y CentOS

Si el servidor utiliza firewalld:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

Aplicamos los cambios:

sudo firewall-cmd --reload

Y comprobamos las reglas activas:

sudo firewall-cmd --list-all

5. Comprobar que Nginx funciona

Podemos realizar una prueba directamente desde el servidor:

curl localhost

Si Nginx está funcionando recibiremos el HTML de la página predeterminada.

También podemos introducir en nuestro navegador:

http://IP_DEL_SERVIDOR

Por ejemplo:

http://185.230.55.45

Si tenemos un dominio correctamente configurado mediante DNS también podremos utilizar:

http://midominio.com

Debería mostrarse la página de bienvenida de Nginx.


6. ¿Dónde guarda Nginx sus archivos?

En Ubuntu y Debian encontraremos la mayor parte de la configuración dentro de:

/etc/nginx/

Algunos de los directorios más importantes son:

/etc/nginx/nginx.conf
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
/etc/nginx/conf.d/

El archivo principal es:

/etc/nginx/nginx.conf

Los registros se almacenan normalmente en:

/var/log/nginx/access.log
/var/log/nginx/error.log

Y la página web predeterminada de Ubuntu/Debian suele encontrarse en:

/var/www/html/

7. Crear nuestra primera página web con Nginx

Supongamos que queremos publicar:

midominio.com

Creamos un directorio independiente:

sudo mkdir -p /var/www/midominio.com/public

Podemos asignarlo al usuario utilizado por Nginx en Debian/Ubuntu:

sudo chown -R www-data:www-data /var/www/midominio.com

Configuramos permisos:

sudo chmod -R 755 /var/www/midominio.com

Ahora creamos una pequeña página de prueba:

sudo nano /var/www/midominio.com/public/index.html

Por ejemplo:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi servidor Nginx</title>
</head>

<body>
    <h1>Nginx funciona correctamente</h1>
    <p>Esta página está siendo servida desde nuestro propio servidor Linux.</p>
</body>
</html>

Guardamos el archivo.


8. Crear un Virtual Host

Nginx utiliza bloques server para decidir qué configuración debe utilizar dependiendo del dominio solicitado.

Creamos un nuevo archivo:

sudo nano /etc/nginx/sites-available/midominio.com

Añadimos:

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

    server_name midominio.com www.midominio.com;

    root /var/www/midominio.com/public;
    index index.html;

    access_log /var/log/nginx/midominio-access.log;
    error_log /var/log/nginx/midominio-error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}

Ahora activamos esta configuración:

sudo ln -s /etc/nginx/sites-available/midominio.com /etc/nginx/sites-enabled/

Antes de aplicar cualquier modificación es muy recomendable comprobar la sintaxis:

sudo nginx -t

Si aparece un resultado similar a:

syntax is ok
test is successful

podemos recargar Nginx:

sudo systemctl reload nginx

Nuestro dominio ya debería mostrar el contenido ubicado en:

/var/www/midominio.com/public/

9. Entender los bloques location

Una parte muy importante de Nginx son las reglas location.

Por ejemplo:

location / {
    try_files $uri $uri/ =404;
}

Esta regla procesa todas las solicitudes que comiencen desde /.

Podemos crear reglas específicas para determinados directorios.

Ejemplo:

location /imagenes/ {
    root /var/www/midominio.com;
}

También podemos realizar coincidencias exactas:

location = /robots.txt {
    access_log off;
}

O utilizar expresiones regulares:

location ~* \.(jpg|jpeg|png|gif|webp|svg)$ {
    expires 30d;
}

Esto último permite aplicar una configuración determinada a varios tipos de archivo.


10. Habilitar caché para contenido estático

Para reducir solicitudes repetidas podemos indicar al navegador que mantenga determinados archivos en caché.

Por ejemplo:

location ~* \.(css|js|jpg|jpeg|png|gif|svg|woff|woff2)$ {
    expires 30d;
    add_header Cache-Control "public";
}

Después comprobamos la configuración:

sudo nginx -t

Y recargamos:

sudo systemctl reload nginx

11. Activar compresión Gzip

Nginx puede comprimir determinados contenidos antes de enviarlos al navegador.

Dentro del bloque http de /etc/nginx/nginx.conf podemos configurar:

gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1000;

gzip_types
    text/plain
    text/css
    application/json
    application/javascript
    application/xml
    image/svg+xml;

Esto puede reducir el volumen de datos transferidos principalmente en archivos de texto, CSS y JavaScript.


12. Ajustes básicos de rendimiento

Nginx permite aprovechar automáticamente los núcleos disponibles configurando:

worker_processes auto;

En el bloque events podemos establecer:

events {
    worker_connections 4096;
    multi_accept on;
}

En sistemas Linux también puede utilizarse:

use epoll;

Por ejemplo:

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

No existe una configuración universal que sea óptima para todos los servidores. Los valores adecuados dependerán del número de usuarios, memoria disponible, CPU y tipo de aplicación alojada.


13. Ocultar la versión de Nginx

Como pequeño ajuste de seguridad podemos evitar mostrar la versión instalada.

Dentro del contexto http añadimos:

server_tokens off;

Posteriormente:

sudo nginx -t
sudo systemctl reload nginx

14. Añadir cabeceras de seguridad

También podemos incluir algunas cabeceras HTTP desde nuestro bloque server.

Por ejemplo:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

La configuración concreta debe adaptarse a cada web. Algunas políticas demasiado restrictivas pueden impedir el funcionamiento de scripts, iframes o recursos externos.


15. Limitar solicitudes por dirección IP

Nginx dispone de herramientas básicas para controlar el número de solicitudes.

Dentro del bloque http podemos crear una zona:

limit_req_zone $binary_remote_addr zone=web_limit:10m rate=10r/s;

Y posteriormente utilizarla dentro de nuestra web:

location / {
    limit_req zone=web_limit burst=20 nodelay;

    try_files $uri $uri/ =404;
}

Este tipo de limitación puede resultar útil contra determinados abusos, aunque no sustituye una solución específica de mitigación DDoS o un WAF.


16. Restringir una sección por IP

Por ejemplo, imaginemos una herramienta administrativa disponible mediante:

/admin/

Podemos permitir únicamente una IP:

location /admin/ {
    allow 192.0.2.50;
    deny all;
}

También podemos permitir una red completa:

allow 10.0.0.0/24;

17. Bloquear archivos ocultos

Determinados archivos que comienzan por . no deberían ser accesibles públicamente.

Podemos bloquearlos con:

location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

18. Configuración HTTPS

Para servir una web mediante HTTPS necesitaremos un certificado SSL/TLS.

Una configuración básica podría tener esta estructura:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name midominio.com www.midominio.com;

    ssl_certificate /etc/nginx/ssl/midominio.crt;
    ssl_certificate_key /etc/nginx/ssl/midominio.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/midominio.com/public;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

También podemos redirigir todas las visitas HTTP hacia HTTPS:

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

    server_name midominio.com www.midominio.com;

    return 301 https://$host$request_uri;
}

19. Consultar los logs de Nginx

Cuando una página no funciona correctamente, los registros suelen ser uno de los primeros lugares que debemos revisar.

Para consultar las solicitudes en tiempo real:

sudo tail -f /var/log/nginx/access.log

Para observar los errores:

sudo tail -f /var/log/nginx/error.log

También podemos mostrar ambos:

sudo tail -f /var/log/nginx/*.log

Si utilizamos registros independientes para cada dominio podremos localizar problemas con mayor facilidad.


20. Comandos esenciales de Nginx

Estos son algunos de los comandos que utilizaremos con más frecuencia.

Comprobar la configuración

sudo nginx -t

Recargar la configuración

sudo systemctl reload nginx

Reiniciar completamente Nginx

sudo systemctl restart nginx

Detener el servicio

sudo systemctl stop nginx

Iniciar el servicio

sudo systemctl start nginx

Consultar el estado

sudo systemctl status nginx

21. Nginx no arranca: qué revisar

Podemos consultar los últimos mensajes del servicio mediante:

sudo journalctl -u nginx -n 50 --no-pager

Y revisar también:

sudo tail -n 50 /var/log/nginx/error.log

Entre los problemas habituales están:

  • Un error de sintaxis.
  • Otro programa utilizando el puerto 80 o 443.
  • Permisos incorrectos.
  • Una ruta inexistente.
  • Un certificado SSL mal configurado.

22. Saber qué aplicación utiliza el puerto 80

Podemos comprobarlo con:

sudo ss -tulpn | grep :80

Otra posibilidad es:

sudo lsof -i :80

Si Apache, otro Nginx u otra aplicación ya utilizan ese puerto tendremos que detenerlos o modificar la configuración.


23. Error 502 Bad Gateway

El conocido error:

502 Bad Gateway

suele aparecer cuando Nginx funciona como proxy o gateway pero no puede comunicarse correctamente con el servicio que tiene detrás.

Si utilizamos PHP-FPM, por ejemplo, podemos comprobar su estado:

sudo systemctl status php-fpm

En Ubuntu, dependiendo de la versión instalada, el servicio puede incluir la versión de PHP en el nombre:

sudo systemctl status php8.3-fpm

También debemos comprobar que el socket o puerto configurado en Nginx coincida con el utilizado por PHP-FPM.


24. Error 413 Request Entity Too Large

Si Nginx rechaza archivos grandes podemos modificar:

client_max_body_size 20M;

Puede configurarse dentro de http, server o determinadas ubicaciones dependiendo de dónde queramos aplicar el límite.

Después:

sudo nginx -t
sudo systemctl reload nginx

25. Hacer una copia de seguridad antes de modificar Nginx

Antes de realizar cambios importantes es conveniente guardar la configuración existente.

Por ejemplo:

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup

O crear una copia completa:

sudo tar -czf nginx-config-backup.tar.gz /etc/nginx/

De esta manera podremos volver rápidamente a una configuración funcional si cometemos algún error.


26. Mantener Nginx actualizado

En Ubuntu y Debian:

sudo apt update
sudo apt upgrade nginx

En Rocky Linux o AlmaLinux:

sudo dnf update nginx

Mantener el servidor actualizado permite recibir correcciones de errores y actualizaciones de seguridad.


Conclusión

Instalar Nginx es relativamente sencillo, pero su verdadero potencial aparece cuando empezamos a trabajar con virtual hosts, proxies, caché, limitación de peticiones, HTTPS y optimización de conexiones.

Para una instalación básica en Ubuntu o Debian, los pasos esenciales se pueden resumir en:

sudo apt update
sudo apt install nginx -y
sudo systemctl enable --now nginx
sudo nginx -t

A partir de ahí podemos crear configuraciones independientes para cada dominio y adaptar Nginx a las necesidades de nuestra infraestructura.

Una recomendación importante es ejecutar siempre:

sudo nginx -t

antes de recargar o reiniciar el servicio. Una comprobación de unos segundos puede evitar dejar todas las páginas del servidor fuera de servicio por un pequeño error de configuración.