Server Blocks de Nginx: Aloja Varios Dominios en un VPS

10 min de lectura·Matthieu|

Configura server blocks de Nginx para servir varios sitios web desde un solo VPS. Dos dominios completos, valores seguros por defecto, logs por sitio y verificación en cada paso.

Un solo VPS puede servir decenas de sitios web. Nginx usa server blocks para decidir qué sitio servir según el nombre de dominio de la petición. Esta guía cubre la configuración completa: dos dominios configurados desde cero, valores seguros por defecto, logs por sitio y verificación en cada paso.

Este tutorial está dirigido a Debian 12 y Ubuntu 24.04. Ambos usan el mismo patrón sites-available/sites-enabled. Los comandos funcionan igual en los dos sistemas operativos.

¿Qué es un server block de Nginx?

Un server block es un bloque de configuración dentro de Nginx que define cómo se gestionan las peticiones para un dominio específico. Es el equivalente en Nginx del virtual host de Apache. Cada server block usa la directiva listen para enlazarse a un puerto y la directiva server_name para hacer coincidir el nombre de dominio con la cabecera Host de la petición. Puedes tener tantos server blocks como necesites, todos compartiendo el puerto 80 o 443.

Requisitos previos

Antes de empezar, necesitas:

  • Nginx instalado y en ejecución
  • Dos dominios con registros DNS A apuntando a la IP de tu servidor
  • Un firewall que permita los puertos 80 y 443
  • Acceso SSH como usuario no root con sudo

Verifica que Nginx está en ejecución:

sudo systemctl status nginx

Deberías ver active (running) en la salida. Si no, inícialo y habilítalo:

sudo systemctl enable --now nginx

El flag enable hace que Nginx arranque automáticamente tras reinicios. El flag --now lo inicia de inmediato.

Verifica que tus registros DNS resuelven a tu servidor. Reemplaza los dominios con los tuyos en toda esta guía:

dig +short site-one.com
dig +short site-two.com

Ambos deben devolver la IP pública de tu servidor.

¿Cómo crear un server block para un nuevo dominio?

El proceso tiene tres partes: crear el directorio raíz del documento, establecer permisos y escribir el archivo de configuración del server block. Configuraremos dos dominios: site-one.com y site-two.com.

¿Qué estructura de directorios usar?

Crea una raíz de documento separada para cada sitio en /var/www/:

sudo mkdir -p /var/www/site-one.com/html
sudo mkdir -p /var/www/site-two.com/html

Crea una página de prueba para cada sitio para poder verificar qué dominio sirve qué contenido:

echo '<h1>Site One</h1>' | sudo tee /var/www/site-one.com/html/index.html
echo '<h1>Site Two</h1>' | sudo tee /var/www/site-two.com/html/index.html

¿Qué permisos necesita la raíz web?

Nginx ejecuta sus procesos worker como el usuario www-data. Los directorios raíz web deben ser legibles por este usuario.

sudo chown -R www-data:www-data /var/www/site-one.com
sudo chown -R www-data:www-data /var/www/site-two.com

Establece los permisos en 755 (el propietario puede leer/escribir/ejecutar, grupo y otros pueden leer y navegar):

sudo chmod -R 755 /var/www/site-one.com
sudo chmod -R 755 /var/www/site-two.com

Verifica la propiedad y los permisos:

ls -la /var/www/

Salida esperada:

drwxr-xr-x  2 www-data www-data 4096 Mar 19 10:00 site-one.com
drwxr-xr-x  2 www-data www-data 4096 Mar 19 10:00 site-two.com

¿Por qué www-data y no tu usuario? En producción, el usuario del servidor web debe ser el propietario de los archivos estáticos. Si tu aplicación escribe archivos (subidas, cachés), el usuario del servidor web necesita permiso de escritura. Usar tu usuario personal abre un camino desde una vulnerabilidad web hasta tu cuenta SSH.

Crear los archivos de configuración del server block

Nginx en Debian y Ubuntu usa un patrón de dos directorios: los archivos de configuración viven en /etc/nginx/sites-available/ y se activan creando enlaces simbólicos en /etc/nginx/sites-enabled/. Esto te permite deshabilitar un sitio sin eliminar su configuración.

Crea el server block para el primer dominio:

sudo nano /etc/nginx/sites-available/site-one.com
server {
    listen 80;
    listen [::]:80;

    server_name site-one.com www.site-one.com;

    root /var/www/site-one.com/html;
    index index.html;

    access_log /var/log/nginx/site-one.com.access.log;
    error_log /var/log/nginx/site-one.com.error.log;

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

¿Qué hace cada directiva?

  • listen 80 y listen [::]:80 se enlazan al puerto 80 en IPv4 e IPv6.
  • server_name lista los nombres de dominio que gestiona este bloque. Incluye las variantes con y sin www.
  • root apunta a la raíz del documento para este sitio.
  • access_log y error_log escriben archivos de log por sitio. Sin ellos, todos los sitios comparten /var/log/nginx/access.log, lo que complica la depuración.
  • try_files sirve el archivo solicitado, luego lo intenta como directorio y finalmente devuelve 404.

Crea el segundo server block:

sudo nano /etc/nginx/sites-available/site-two.com
server {
    listen 80;
    listen [::]:80;

    server_name site-two.com www.site-two.com;

    root /var/www/site-two.com/html;
    index index.html;

    access_log /var/log/nginx/site-two.com.access.log;
    error_log /var/log/nginx/site-two.com.error.log;

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

¿Cómo habilitar y deshabilitar server blocks?

Los server blocks en sites-available/ están inactivos hasta que se enlazan simbólicamente en sites-enabled/.

Habilitar un sitio

Crea los enlaces simbólicos para ambos dominios:

sudo ln -s /etc/nginx/sites-available/site-one.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site-two.com /etc/nginx/sites-enabled/

Elimina el server block por defecto que viene con Nginx. Entra en conflicto con tus nuevos bloques y sirve la página "Welcome to Nginx":

sudo rm /etc/nginx/sites-enabled/default

Esto solo elimina el enlace simbólico. El archivo original permanece en sites-available/ por si lo necesitas más adelante.

Probar la configuración antes de aplicarla

Prueba siempre la configuración de Nginx antes de recargar. Un error de sintaxis en un archivo tumba todos los sitios:

sudo nginx -t

Salida esperada:

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

Si necesitas ver la configuración fusionada completa (todos los includes resueltos en una sola salida), usa:

sudo nginx -T

Esta es la mejor herramienta para depurar problemas de server block. Muestra exactamente lo que Nginx va a cargar, incluyendo el orden de los server blocks.

Recargar, no reiniciar

Aplica la nueva configuración:

sudo systemctl reload nginx

¿Por qué reload en lugar de restart? Una recarga envía una señal a Nginx para que vuelva a leer sus archivos de configuración. Las conexiones existentes terminan de procesarse con normalidad. Un reinicio mata el proceso y arranca uno nuevo, cortando todas las conexiones activas. En producción, usa siempre reload.

Verifica que la recarga funcionó:

sudo systemctl status nginx

Atención: busca active (running) y comprueba el timestamp en la línea "Main PID". No debe haber cambiado (lo que confirma una recarga, no un reinicio).

Deshabilitar un sitio

Para dejar un sitio fuera de servicio sin eliminar su configuración:

sudo rm /etc/nginx/sites-enabled/site-two.com
sudo nginx -t && sudo systemctl reload nginx

El archivo de configuración permanece en sites-available/. Puedes volver a habilitarlo en cualquier momento creando de nuevo el enlace simbólico.

¿Cómo verificar que tus server blocks funcionan?

No abras un navegador. En un VPS sin interfaz gráfica, usa curl con la cabecera Host para simular peticiones de cada dominio:

curl -H "Host: site-one.com" http://localhost

Salida esperada:

<h1>Site One</h1>
curl -H "Host: site-two.com" http://localhost

Salida esperada:

<h1>Site Two</h1>

Esto funciona incluso antes de que el DNS se propague, porque estás indicando a Nginx directamente qué dominio quieres mediante la cabecera Host.

Una vez que el DNS se haya propagado, prueba desde tu máquina local (no desde el servidor):

curl http://site-one.com
curl http://site-two.com

Cada uno debe devolver la página de prueba correcta.

¿Cómo decide Nginx qué server block gestiona una petición?

Nginx hace coincidir las peticiones entrantes con los server blocks en un orden específico. Cuando llega una petición, Nginx primero filtra los server blocks por la directiva listen (IP y puerto), luego hace coincidir la cabecera Host con los valores de server_name.

¿Cuál es el orden de coincidencia de server_name?

El orden de coincidencia es fijo y no puede modificarse por el orden de los archivos de configuración:

Prioridad Tipo de patrón Ejemplo Cuándo se usa
1 (mayor) Nombre exacto site-one.com Se intenta siempre primero. Más rápido (búsqueda en hash).
2 Prefijo wildcard más largo *.site-one.com Coincide con www.site-one.com, api.site-one.com
3 Sufijo wildcard más largo mail.* Coincide con mail.site-one.com, mail.site-two.com
4 Primera regex coincidente ~^www\d+\.example\.com$ Se evalúa en el orden del archivo de configuración. La primera coincidencia gana.
5 (menor) default_server N/A Fallback cuando nada más coincide.

Puntos clave:

  • Los nombres exactos siempre se comprueban primero, independientemente de dónde aparezca el server block en la configuración.
  • Los nombres wildcard solo pueden tener el * al principio o al final, en un límite de punto. w*.example.com no es válido.
  • Los patrones regex empiezan con ~ y se prueban en el orden en que aparecen en los archivos de configuración. La primera coincidencia gana. Usarlos con moderación porque son el tipo de coincidencia más lento.
  • Si nada coincide y no hay default_server definido, Nginx usa el primer server block en el orden de los archivos de configuración como valor por defecto. Es una fuente habitual de confusión.

¿Qué hace la directiva default_server?

El parámetro default_server en la directiva listen indica a Nginx qué server block gestiona las peticiones cuando ningún server_name coincide. Sin él, Nginx selecciona silenciosamente el primer server block cargado para ese puerto. Esto significa que un dominio mal configurado o un bot que escanea tu IP recibe uno de tus sitios reales.

Crea un server block catch-all (atrapa-todo) que descarta las peticiones sin coincidencia:

sudo nano /etc/nginx/sites-available/00-catch-all
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    return 444;
}

¿Qué hace esto?

  • default_server marca este bloque como el fallback para el puerto 80.
  • server_name _ es una convención para "ningún nombre válido". El guion bajo no es especial para Nginx; simplemente nunca coincide con un hostname real.
  • return 444 es un código no estándar de Nginx que cierra la conexión sin enviar ninguna respuesta. Los bots que escanean tu IP no reciben nada. Ni cabeceras, ni cuerpo, ni información sobre el software que ejecutas.

Habilita y aplica:

sudo ln -s /etc/nginx/sites-available/00-catch-all /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

El nombre de archivo empieza por 00- para que aparezca primero en los listados de directorios. Esto no tiene efecto en el comportamiento de Nginx (la directiva default_server controla la selección, no el orden de los archivos), pero facilita el escaneo de la configuración a los humanos.

Prueba el catch-all solicitando un dominio que no coincida con ningún server block:

curl -v -H "Host: not-my-domain.com" http://localhost

Debería aparecer Empty reply from server porque Nginx cerró la conexión sin respuesta.

¿Cómo configurar logs por sitio?

Cada server block de esta guía ya incluye directivas de log por sitio. Los logs por sitio permiten depurar un sitio sin revisar el tráfico de todos los demás dominios. Las rutas de log se definen en cada server block:

access_log /var/log/nginx/site-one.com.access.log;
error_log /var/log/nginx/site-one.com.error.log;

Sigue los logs en tiempo real:

sudo tail -f /var/log/nginx/site-one.com.access.log

O usa journalctl para los logs del proceso principal de Nginx (errores de arranque, fallos de recarga):

journalctl -u nginx -f

Nginx gestiona la rotación de logs automáticamente mediante /etc/logrotate.d/nginx. La política por defecto rota los logs diariamente y conserva 14 días. No se necesita configuración adicional.

¿Cuáles son los problemas habituales de server block y sus soluciones?

Síntoma Causa Solución
La página "Welcome to Nginx" por defecto aparece en todos los dominios El enlace simbólico default sigue en sites-enabled/ sudo rm /etc/nginx/sites-enabled/default && sudo systemctl reload nginx
El dominio sirve el sitio equivocado server_name duplicado entre bloques, o no se encontró coincidencia exacta Ejecuta `sudo nginx -T
Error could not build server_names_hash Nombres de dominio demasiado largos para el hash bucket por defecto Agrega server_names_hash_bucket_size 128; dentro del bloque http {} en /etc/nginx/nginx.conf
Los cambios no surten efecto después de editar la configuración Se olvidó recargar sudo nginx -t && sudo systemctl reload nginx
bind() to 0.0.0.0:80 failed Otro proceso (Apache, Nginx antiguo) está usando el puerto 80 `sudo ss -tlnp
El enlace simbólico se creó pero el sitio no carga El enlace simbólico apunta a una ruta incorrecta (relativa en lugar de absoluta) Elimina y recrea: sudo ln -sf /etc/nginx/sites-available/site-one.com /etc/nginx/sites-enabled/

Depuración con nginx -T

Cuando un sitio no se comporta como se espera, vuelca la configuración fusionada completa:

sudo nginx -T 2>&1 | grep -A 5 "server_name"

Muestra cada server block con su valor de server_name, permitiéndote ver exactamente lo que Nginx cargó y en qué orden. Resuelve todas las directivas include, por lo que ves la configuración real, no solo los archivos en disco.

Siguientes pasos

Tus server blocks ya sirven varios dominios por HTTP. El siguiente paso es agregar certificados TLS para que estos sitios se sirvan por HTTPS.

Para una visión más amplia de la gestión de Nginx en un VPS, consulta la guía principal.


Copyright 2026 Virtua.Cloud. Todos los derechos reservados. Este contenido es una obra original del equipo de Virtua.Cloud. La reproducción, republicación o redistribución sin permiso escrito está prohibida.

¿Listo para probarlo?

Despliega tu propio servidor en segundos. Linux, Windows o FreeBSD.

Ver planes VPS