Nginx Server Block: ospita più domini su un VPS

10 min di lettura·Matthieu|

Configura più siti su un singolo VPS usando gli Nginx server block. Due domini dal setup iniziale fino alla verifica, con logging separato per sito.

Un singolo VPS può servire decine di siti web. Nginx usa i server block per decidere quale sito servire in base al nome di dominio nella richiesta. Questa guida copre il setup completo: due domini configurati da zero, default sicuri, logging per sito e verifica a ogni step.

Il tutorial è scritto per Debian 12 e Ubuntu 24.04. Entrambi usano lo stesso pattern sites-available/sites-enabled. I comandi funzionano in modo identico su entrambi i sistemi.

Cos'è un Nginx server block?

Un server block è un blocco di configurazione all'interno di Nginx che definisce come vengono gestite le richieste per un dominio specifico. È l'equivalente Nginx dei virtual host di Apache. Ogni server block usa la direttiva listen per associarsi a una porta e la direttiva server_name per fare il match del nome di dominio dall'header Host della richiesta. Si possono avere quanti server block si vuole, tutti condividono la porta 80 o 443.

Prerequisiti

Prima di iniziare ti servono:

  • Nginx installato e in esecuzione
  • Due nomi di dominio con record DNS A che puntano all'IP del server
  • Un firewall che permette le porte 80 e 443
  • Accesso SSH come utente non-root con sudo

Verifica che Nginx sia in esecuzione:

sudo systemctl status nginx

Dovresti vedere active (running) nell'output. Se non lo vedi, avvialo e abilitalo:

sudo systemctl enable --now nginx

Il flag enable fa partire Nginx automaticamente dopo i riavvii. Il flag --now lo avvia subito.

Verifica che i record DNS si risolvano sul tuo server. Sostituisci i domini con i tuoi durante tutta la guida:

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

Entrambi devono restituire l'IP pubblico del tuo server.

Come si crea un server block per un nuovo dominio?

Il processo ha tre parti: creare la directory root del documento, impostare i permessi e scrivere il file di configurazione del server block. Configureremo due domini: site-one.com e site-two.com.

Che struttura di directory usare?

Crea una document root separata per ogni sito sotto /var/www/:

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

Crea una pagina di test per ogni sito per verificare quale dominio serve quale contenuto:

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

Quali permessi servono sulla web root?

Nginx esegue i suoi worker process come utente www-data. Le directory web root devono essere leggibili da questo utente.

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

Imposta i permessi a 755 (il proprietario può leggere/scrivere/eseguire, gruppo e altri possono leggere e attraversare):

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

Verifica proprietà e permessi:

ls -la /var/www/

Output atteso:

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

Perché www-data e non il tuo utente? In produzione il web server deve essere proprietario dei file statici. Se la tua applicazione scrive file (upload, cache), l'utente del web server ha bisogno dell'accesso in scrittura. Usare il tuo utente personale apre un percorso da una vulnerabilità web al tuo account SSH.

Crea i file di configurazione dei server block

Nginx su Debian e Ubuntu usa un pattern a due directory: i file di configurazione risiedono in /etc/nginx/sites-available/ e vengono attivati creando un symlink in /etc/nginx/sites-enabled/. Questo ti permette di disabilitare un sito senza cancellarne la configurazione.

Crea il server block per il primo 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;
    }
}

Cosa fa ogni direttiva:

  • listen 80 e listen [::]:80 si associano alla porta 80 su IPv4 e IPv6.
  • server_name elenca i nomi di dominio gestiti da questo blocco. Includi sia la variante base che quella www.
  • root punta alla document root del sito.
  • access_log e error_log scrivono file di log separati per sito. Senza queste direttive, tutti i siti condividono /var/log/nginx/access.log, rendendo il debug difficile.
  • try_files serve il file richiesto, poi lo prova come directory, poi restituisce 404.

Crea il secondo 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;
    }
}

Come si abilitano e disabilitano i server block?

I server block in sites-available/ sono inattivi finché non vengono collegati con un symlink in sites-enabled/.

Abilitare un sito

Crea i symlink per entrambi i domini:

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/

Rimuovi il server block di default fornito con Nginx. Entra in conflitto con i nuovi blocchi e serve la pagina "Welcome to Nginx":

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

Questo rimuove solo il symlink. Il file originale rimane in sites-available/ nel caso ti serva in seguito.

Testa la configurazione prima di applicarla

Testa sempre la configurazione Nginx prima di ricaricarla. Un errore di sintassi in un file mette offline tutti i siti:

sudo nginx -t

Output atteso:

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

Se hai bisogno di vedere la configurazione completa unificata (tutti gli include risolti in un unico output), usa:

sudo nginx -T

È lo strumento migliore per il debug dei server block. Mostra esattamente cosa Nginx caricherà, incluso l'ordine dei server block.

Reload, non restart

Applica la nuova configurazione:

sudo systemctl reload nginx

Perché reload invece di restart? Un reload invia un segnale a Nginx per rileggere i file di configurazione. Le connessioni esistenti terminano normalmente. Un restart uccide il processo e ne avvia uno nuovo, interrompendo tutte le connessioni attive. In produzione, usa sempre il reload.

Verifica che il reload sia andato a buon fine:

sudo systemctl status nginx

Osserva: cerca active (running) e controlla il timestamp sulla riga "Main PID". Non dovrebbe essere cambiato (conferma un reload, non un restart).

Disabilitare un sito

Per portare un sito offline senza cancellarne la configurazione:

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

Il file di configurazione rimane in sites-available/. Riabilitalo in qualsiasi momento ricreando il symlink.

Come si verifica che i server block funzionino?

Non aprire un browser. Su un VPS headless, usa curl con l'header Host per simulare richieste da ciascun dominio:

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

Output atteso:

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

Output atteso:

<h1>Site Two</h1>

Questo funziona anche prima che il DNS si propaghi, perché stai dicendo a Nginx direttamente quale dominio vuoi tramite l'header Host.

Una volta propagato il DNS, testa dalla tua macchina locale (non dal server):

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

Ognuno deve restituire la pagina di test corretta.

Come decide Nginx quale server block gestisce una richiesta?

Nginx fa il match delle richieste in arrivo ai server block in un ordine specifico. Quando arriva una richiesta, Nginx filtra prima i server block in base alla direttiva listen (IP e porta), poi fa il match dell'header Host con i valori di server_name.

Qual è l'ordine di matching di server_name?

L'ordine di matching è fisso e non può essere cambiato dall'ordine dei file di configurazione:

Priorità Tipo di pattern Esempio Quando si usa
1 (massima) Nome esatto site-one.com Sempre il primo. Più veloce (hash lookup).
2 Wildcard prefix più lungo *.site-one.com Match di www.site-one.com, api.site-one.com
3 Wildcard suffix più lungo mail.* Match di mail.site-one.com, mail.site-two.com
4 Prima regex corrispondente ~^www\d+\.example\.com$ Valutata nell'ordine dei file di config. Vince il primo match.
5 (minima) default_server N/A Fallback quando nulla corrisponde.

Punti chiave:

  • I nomi esatti vengono sempre controllati per primi, indipendentemente da dove appare il server block nella configurazione.
  • I nomi wildcard possono avere il * solo all'inizio o alla fine, su un confine di punto. w*.example.com non è valido.
  • I pattern regex iniziano con ~ e vengono testati nell'ordine in cui appaiono nei file di configurazione. Vince il primo match. Usarli con parsimonia perché sono il tipo di match più lento.
  • Se nulla corrisponde e non è impostato alcun default_server, Nginx usa il primo server block nell'ordine dei file di configurazione come default. Questa è una fonte comune di confusione.

Cosa fa la direttiva default_server?

Il parametro default_server sulla direttiva listen dice a Nginx quale server block gestisce le richieste quando nessun server_name corrisponde. Senza di esso, Nginx sceglie silenziosamente il primo server block caricato per quella porta. Questo significa che un dominio mal configurato o un bot che scansiona il tuo IP riceve uno dei tuoi siti reali.

Crea un server block catch-all che scarta le richieste senza corrispondenza:

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

    server_name _;

    return 444;
}

Cosa fa:

  • default_server segna questo blocco come fallback per la porta 80.
  • server_name _ è una convenzione per "nessun nome valido". Il trattino basso non ha significato speciale per Nginx; semplicemente non fa mai match con un hostname reale.
  • return 444 è un codice non standard di Nginx che chiude la connessione senza inviare alcuna risposta. I bot che scansionano il tuo IP non ottengono nulla. Nessun header, nessun body, nessuna informazione sul software in esecuzione.

Abilita e applica:

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

Il nome del file inizia con 00- per essere il primo nell'ordinamento delle directory. Questo non ha effetto sul comportamento di Nginx (la direttiva default_server controlla la selezione, non l'ordine dei file), ma rende la configurazione più facile da leggere per gli umani.

Testa il catch-all richiedendo un dominio che non corrisponde ad alcun server block:

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

Dovresti vedere Empty reply from server perché Nginx ha chiuso la connessione senza risposta.

Come si imposta il logging per sito?

Ogni server block in questa guida include già le direttive di log per sito. I log per sito ti permettono di fare debug su un singolo sito senza dover setacciare il traffico di tutti gli altri domini. I percorsi dei log sono impostati in ogni server block:

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

Segui i log in tempo reale:

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

Oppure usa journalctl per i log del processo principale di Nginx (errori di avvio, fallimenti del reload):

journalctl -u nginx -f

Nginx gestisce la rotazione dei log automaticamente tramite /etc/logrotate.d/nginx. La policy di default ruota i log giornalmente e conserva 14 giorni. Non è necessaria nessuna configurazione aggiuntiva.

Problemi comuni dei server block e soluzioni

Sintomo Causa Soluzione
La pagina "Welcome to Nginx" appare per tutti i domini Il symlink default è ancora in sites-enabled/ sudo rm /etc/nginx/sites-enabled/default && sudo systemctl reload nginx
Viene servito il sito sbagliato per un dominio server_name duplicato tra i blocchi, o nessun match esatto trovato Esegui `sudo nginx -T
Errore could not build server_names_hash I nomi di dominio sono troppo lunghi per l'hash bucket di default Aggiungi server_names_hash_bucket_size 128; dentro il blocco http {} in /etc/nginx/nginx.conf
Le modifiche non hanno effetto dopo aver modificato la configurazione Si è dimenticato il reload sudo nginx -t && sudo systemctl reload nginx
bind() to 0.0.0.0:80 failed Un altro processo (Apache, un vecchio Nginx) sta usando la porta 80 `sudo ss -tlnp
Symlink creato ma il sito non si carica Il symlink punta al percorso sbagliato (relativo invece di assoluto) Cancella e ricrea: sudo ln -sf /etc/nginx/sites-available/site-one.com /etc/nginx/sites-enabled/

Debug con nginx -T

Quando un sito non si comporta come previsto, visualizza la configurazione unificata completa:

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

Mostra ogni server block con il suo valore server_name, permettendoti di vedere esattamente cosa ha caricato Nginx e in che ordine. Risolve tutte le direttive include, quindi vedi la configurazione reale, non solo i file su disco.

Prossimi passi

I tuoi server block ora servono più domini via HTTP. Il passo successivo è aggiungere i certificati TLS per servire questi siti via HTTPS.

Per una panoramica più ampia della gestione di Nginx su un VPS, vedi la guida principale.


Copyright 2026 Virtua.Cloud. Tutti i diritti riservati. Questo contenuto è un'opera originale del team Virtua.Cloud. La riproduzione, ripubblicazione o redistribuzione senza autorizzazione scritta è vietata.

Pronto a provare?

Distribuisci il tuo server in pochi secondi. Linux, Windows o FreeBSD.

Vedi piani VPS