--- title: "Cómo instalar y configurar Nginx en Ubuntu 24.04" description: "Instala Nginx en Ubuntu 24.04, abre el firewall, crea un server block, ajusta nginx.conf, activa compresión y cabeceras de seguridad y añade HTTPS con Certbot." category: "Servidores Web" language: es source: https://cubepath.com/es/docs/servidores-web/instalacion-y-configuracion-de-nginx-en-linux updated: 2026-09-25 --- # Cómo instalar y configurar Nginx en Ubuntu 24.04 Nginx es un servidor web de arquitectura orientada a eventos que sirve contenido estático con muy poco consumo de memoria y se usa mucho como proxy inverso y balanceador delante de aplicaciones. En este tutorial instalarás Nginx en Ubuntu 24.04, abrirás el firewall, publicarás un sitio en su propio server block, ajustarás la configuración global, activarás compresión y cabeceras de seguridad y lo protegerás con un certificado de Let's Encrypt. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - UFW activo con SSH permitido (`sudo ufw allow OpenSSH`). - Para el paso de HTTPS: un dominio (en esta guía, `your_domain`) con un registro DNS `A` que apunte a la IP pública del servidor, y opcionalmente otro para `www.your_domain`. - Ningún otro servidor web (por ejemplo Apache) escuchando en los puertos 80 y 443. ## Paso 1: Instalar Nginx La versión de Nginx de los repositorios de Ubuntu 24.04 (1.24) es estable y recibe parches de seguridad durante todo el ciclo de vida de la distribución. Es la opción recomendada para la mayoría de servidores: ```bash sudo apt update sudo apt install nginx ``` El servicio arranca y queda habilitado en el inicio. Compruébalo: ```bash sudo systemctl status nginx --no-pager ``` ```output ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-24 10:20:41 UTC; 8s ago ``` ```bash nginx -v ``` ```output nginx version: nginx/1.24.0 (Ubuntu) ``` ### Alternativa: repositorio oficial de nginx.org Si necesitas una versión más reciente (por ejemplo para usar la directiva `http2 on;` o HTTP/3), puedes usar el repositorio de nginx.org en lugar del paquete de Ubuntu. Hazlo antes de instalar `nginx` o desinstala primero el paquete de Ubuntu. ```bash sudo apt install curl gnupg2 ca-certificates lsb-release curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /etc/apt/keyrings/nginx.gpg echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list sudo apt update sudo apt install nginx sudo systemctl enable --now nginx ``` > Importante: el paquete de nginx.org no usa `sites-available` ni `sites-enabled`. Sus sitios se definen en `/etc/nginx/conf.d/*.conf`, trabaja con el usuario `nginx` en lugar de `www-data` y no registra perfiles en UFW. El resto de esta guía usa el paquete de Ubuntu. ## Paso 2: Abrir el firewall Nginx registra tres perfiles de UFW: `Nginx HTTP` (puerto 80), `Nginx HTTPS` (443) y `Nginx Full` (ambos). Permite los dos puertos: ```bash sudo ufw allow 'Nginx Full' sudo ufw status ``` ```output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6) ``` Comprueba que el servidor responde: ```bash curl -I http://localhost ``` ```output HTTP/1.1 200 OK Server: nginx/1.24.0 (Ubuntu) Content-Type: text/html ``` Desde el navegador, `http://your_server_ip` muestra la página "Welcome to nginx!". ## Paso 3: Conocer la estructura de configuración | Ruta | Contenido | |------|-----------| | `/etc/nginx/nginx.conf` | Configuración global: procesos, bloque `http`, includes | | `/etc/nginx/sites-available/` | Un archivo por sitio (server block) | | `/etc/nginx/sites-enabled/` | Enlaces simbólicos a los sitios activos | | `/etc/nginx/conf.d/` | Fragmentos que se cargan dentro del bloque `http` | | `/etc/nginx/snippets/` | Fragmentos reutilizables, como `fastcgi-php.conf` | | `/var/www/html/` | Raíz web del sitio por defecto | | `/var/log/nginx/` | `access.log` y `error.log` | La configuración de Nginx se organiza en contextos anidados: `main` (el nivel superior de `nginx.conf`), `events`, `http`, `server` (un sitio) y `location` (una ruta dentro del sitio). Una directiva definida en `http` se hereda en todos los `server` salvo que la redefinas. ## Paso 4: Ajustar la configuración global Abre el archivo principal: ```bash sudo nano /etc/nginx/nginx.conf ``` Los valores de Ubuntu ya son razonables: `worker_processes auto;` crea un proceso por núcleo de CPU y `worker_connections 768;` limita las conexiones por proceso. Dentro del bloque `http { ... }`, cambia o añade estas directivas: ```nginx server_tokens off; client_max_body_size 20m; server_names_hash_bucket_size 64; ``` - `server_tokens off;` oculta la versión en la cabecera `Server` y en las páginas de error. - `client_max_body_size` sube el límite de subida por defecto (1 MB), que provoca errores 413 en formularios con archivos. - `server_names_hash_bucket_size 64;` evita el error `could not build server_names_hash` con nombres de dominio largos. En Ubuntu ya aparece comentada: basta con quitar el `#`. En el mismo bloque `http`, Ubuntu trae `gzip on;` pero con el resto de opciones comentadas, así que solo comprime HTML. Descomenta o añade estas líneas para comprimir también CSS, JavaScript, JSON y SVG: ```nginx gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml; ``` Guarda, comprueba la sintaxis y recarga: ```bash sudo nginx -t sudo systemctl reload nginx ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` > Consejo: usa siempre `reload` en lugar de `restart` tras cambiar la configuración. Nginx arranca procesos nuevos con la configuración nueva y deja terminar las conexiones abiertas, sin cortar el servicio. Si la sintaxis es incorrecta, sigue funcionando con la anterior. ## Paso 5: Crear un server block para tu dominio Crea el directorio del sitio con una página de prueba: ```bash sudo mkdir -p /var/www/your_domain/html sudo chown -R $USER:$USER /var/www/your_domain nano /var/www/your_domain/html/index.html ``` ```html your_domain

El server block de your_domain funciona

``` Crea el archivo del sitio: ```bash sudo nano /etc/nginx/sites-available/your_domain ``` ```nginx server { listen 80; listen [::]:80; server_name your_domain www.your_domain; root /var/www/your_domain/html; index index.html; access_log /var/log/nginx/your_domain.access.log; error_log /var/log/nginx/your_domain.error.log; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; location / { try_files $uri $uri/ =404; } location ~ /\.(?!well-known) { deny all; } location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|woff2)$ { expires 30d; access_log off; } } ``` Qué hace cada parte: - `try_files` busca el archivo o directorio pedido y devuelve 404 si no existe. - La `location` con `/\.` bloquea archivos ocultos como `.git` o `.env`, pero deja pasar `/.well-known/`, que Let's Encrypt necesita. - La última `location` indica al navegador que guarde en caché los recursos estáticos durante 30 días. > Nota: `add_header` solo se hereda si el bloque hijo no define ningún `add_header` propio. Si añades uno dentro de una `location`, repite en ella las cabeceras de seguridad. Activa el sitio con un enlace simbólico, desactiva el sitio por defecto y recarga: ```bash sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx ``` Comprueba la respuesta aunque el DNS no haya propagado todavía: ```bash curl -i --resolve your_domain:80:127.0.0.1 http://your_domain ``` ```output HTTP/1.1 200 OK Server: nginx X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Referrer-Policy: strict-origin-when-cross-origin

El server block de your_domain funciona

``` La cabecera `Server` ya no muestra la versión gracias a `server_tokens off;`. ## Paso 6: Limitar la tasa de peticiones (opcional) Si el sitio tiene un formulario de login o una API, limitar las peticiones por IP frena los ataques de fuerza bruta. Define una zona compartida en el contexto `http` creando un archivo en `conf.d`: ```bash sudo nano /etc/nginx/conf.d/ratelimit.conf ``` ```nginx limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m; ``` Aplica el límite solo a la ruta sensible dentro del server block de `your_domain`: ```nginx location = /login { limit_req zone=login burst=5 nodelay; limit_req_status 429; try_files $uri $uri/ =404; } ``` Sustituye `try_files` por lo que sirva realmente esa ruta en tu sitio (por ejemplo un `proxy_pass` o `fastcgi_pass`). Tras `sudo nginx -t` y `sudo systemctl reload nginx`, las peticiones que superen 5 por minuto (más una ráfaga de 5) recibirán un `429 Too Many Requests`. ## Paso 7: Añadir HTTPS con Let's Encrypt Instala Certbot y su plugin para Nginx: ```bash sudo apt install certbot python3-certbot-nginx ``` Solicita el certificado. Certbot localiza el server block por `server_name`, añade la configuración TLS y crea la redirección de HTTP a HTTPS: ```bash sudo certbot --nginx -d your_domain -d www.your_domain ``` Comprueba la redirección y el acceso por HTTPS: ```bash curl -I http://your_domain curl -I https://your_domain ``` ```output HTTP/1.1 301 Moved Permanently Location: https://your_domain/ HTTP/1.1 200 OK Server: nginx ``` El temporizador `certbot.timer` renueva el certificado antes de que caduque. Simula una renovación para confirmar que funcionará: ```bash sudo certbot renew --dry-run ``` ## Paso 8: Revisar los logs Sigue las peticiones del sitio en tiempo real: ```bash sudo tail -f /var/log/nginx/your_domain.access.log ``` Consulta los errores recientes: ```bash sudo tail -n 50 /var/log/nginx/your_domain.error.log ``` Para ver la configuración completa que Nginx está usando, con todos los `include` resueltos, ejecuta `sudo nginx -T`. Es la forma más rápida de encontrar una directiva duplicada. ## Solución de problemas **`nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)`**: otro servicio, normalmente Apache, ocupa el puerto. Compruébalo con `sudo ss -tlnp | grep ':80 '` y detén ese servicio (`sudo systemctl disable --now apache2`) si no lo necesitas. **`conflicting server name "your_domain" on 0.0.0.0:80, ignored`**: el mismo `server_name` aparece en dos server blocks activos. Búscalo con `grep -r "server_name" /etc/nginx/sites-enabled/` y deja solo uno. **403 Forbidden**: no hay archivo índice en el directorio o el usuario `www-data` no puede leer los archivos. `namei -l /var/www/your_domain/html/index.html` muestra los permisos de cada directorio de la ruta. **413 Request Entity Too Large**: la subida supera `client_max_body_size`. Súbelo en el bloque `http` o solo en el server block afectado. **502 Bad Gateway**: Nginx no puede conectar con el backend (PHP-FPM o una aplicación en `proxy_pass`). Comprueba que el servicio está activo y que la ruta del socket o el puerto coinciden; el log de errores indica cuál intentó usar. ## Conclusión Has instalado Nginx en Ubuntu 24.04, abierto el firewall, ajustado la configuración global, publicado un sitio con compresión, caché de estáticos y cabeceras de seguridad, y activado HTTPS con renovación automática. Como siguientes pasos puedes: - Alojar varios dominios en el mismo servidor siguiendo la guía de server blocks en Nginx. - Instalar PHP-FPM (`php8.3-fpm`) para servir aplicaciones PHP. - Usar Nginx como proxy inverso delante de una aplicación Node.js, Python o un contenedor Docker.