Nginx server blocks: meerdere domeinen op één VPS
Leer hoe je met Nginx server blocks meerdere domeinen op één VPS host: mapstructuur, rechten, logging per site en een catch-all block voor onbekende aanvragen.
Een enkele VPS kan tientallen websites bedienen. Nginx gebruikt server blocks om te bepalen welke site geserveerd wordt op basis van de domeinnaam in de aanvraag. Deze handleiding behandelt de volledige setup: twee domeinen geconfigureerd van nul, secure defaults, logging per site en verificatie bij elke stap.
Deze tutorial richt zich op Debian 12 en Ubuntu 24.04. Beide gebruiken hetzelfde sites-available/sites-enabled-patroon. Commando's werken identiek op beide besturingssystemen.
Wat is een Nginx server block?
Een server block is een configuratieblok in Nginx dat bepaalt hoe aanvragen voor een specifiek domein worden afgehandeld. Het is het Nginx-equivalent van Apache's virtual host. Elk server block gebruikt de listen-directive om te binden aan een poort en de server_name-directive om de domeinnaam te matchen vanuit de Host-header van de aanvraag. Je kunt zoveel server blocks hebben als nodig, allemaal op poort 80 of 443.
Vereisten
Voor je begint heb je nodig:
- Nginx geïnstalleerd en actief
- Twee domeinnamen met DNS A-records die wijzen naar het IP-adres van je server
- Een firewall die poorten 80 en 443 toelaat
- SSH-toegang als niet-root gebruiker met
sudo
Controleer of Nginx actief is:
sudo systemctl status nginx
Je zou active (running) moeten zien in de uitvoer. Zo niet, start en activeer het:
sudo systemctl enable --now nginx
De enable-vlag zorgt dat Nginx automatisch start na een herstart. De --now-vlag start het direct.
Controleer of je DNS-records verwijzen naar je server. Vervang de domeinen door je eigen domeinen in deze handleiding:
dig +short site-one.com
dig +short site-two.com
Beide zouden het publieke IP-adres van je server moeten teruggeven.
Hoe maak je een server block aan voor een nieuw domein?
Het proces bestaat uit drie onderdelen: maak de document root-map aan, stel rechten in en schrijf het server block-configuratiebestand. We configureren twee domeinen: site-one.com en site-two.com.
Welke mapstructuur gebruik je?
Maak een aparte document root aan voor elke site onder /var/www/:
sudo mkdir -p /var/www/site-one.com/html
sudo mkdir -p /var/www/site-two.com/html
Maak een testpagina aan voor elke site zodat je kunt verifiëren welk domein welke inhoud serveert:
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
Welke rechten heeft de web root nodig?
Nginx voert zijn worker processes uit als de www-data-gebruiker. De web root-mappen moeten leesbaar zijn voor deze gebruiker.
sudo chown -R www-data:www-data /var/www/site-one.com
sudo chown -R www-data:www-data /var/www/site-two.com
Stel rechten in op 755 (eigenaar kan lezen/schrijven/uitvoeren, groep en anderen kunnen lezen en doorlopen):
sudo chmod -R 755 /var/www/site-one.com
sudo chmod -R 755 /var/www/site-two.com
Controleer de eigenaar en rechten:
ls -la /var/www/
Verwachte uitvoer:
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
Waarom www-data en niet je eigen gebruiker? In productie moet de webservergebruiker eigenaar zijn van statische bestanden. Als je applicatie bestanden schrijft (uploads, caches), heeft de webservergebruiker schrijfrechten nodig. Je persoonlijke gebruiker als eigenaar opent een pad van een webkwetsbaarheid naar je SSH-account.
Maak de server block-configuratiebestanden aan
Nginx op Debian en Ubuntu gebruikt een twee-mappenpatroon: configuratiebestanden staan in /etc/nginx/sites-available/ en worden geactiveerd door een symlink te maken in /etc/nginx/sites-enabled/. Zo kun je een site uitschakelen zonder de configuratie te verwijderen.
Maak het server block aan voor het eerste domein:
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;
}
}
Wat elke directive doet:
listen 80enlisten [::]:80binden aan poort 80 op IPv4 en IPv6.server_namegeeft de domeinnamen op die dit block afhandelt. Neem zowel het kale domein als dewww-variant op.rootwijst naar de document root voor deze site.access_logenerror_logschrijven per-site logbestanden. Zonder deze instelling delen alle sites/var/log/nginx/access.log, wat debuggen lastig maakt.try_filesserveert het gevraagde bestand, probeert het dan als map, en geeft anders 404 terug.
Maak het tweede server block aan:
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;
}
}
Hoe activeer en deactiveer je server blocks?
Server blocks in sites-available/ zijn inactief totdat ze gesymlinkt worden in sites-enabled/.
Een site activeren
Maak symlinks aan voor beide domeinen:
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/
Verwijder het standaard server block dat met Nginx meekomt. Dit conflicteert met je nieuwe blocks en serveert de "Welcome to Nginx"-pagina:
sudo rm /etc/nginx/sites-enabled/default
Dit verwijdert alleen de symlink. Het originele bestand blijft in sites-available/ voor het geval je het later nodig hebt.
Test de configuratie voor je deze toepast
Test de Nginx-configuratie altijd voor je herlaadt. Een syntaxfout in één bestand legt alle sites plat:
sudo nginx -t
Verwachte uitvoer:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Als je de volledige samengevoegde configuratie wil zien (alle includes opgelost in één uitvoer), gebruik:
sudo nginx -T
Dit is het beste hulpmiddel voor het debuggen van server block-problemen. Het toont precies wat Nginx laadt, inclusief de volgorde van server blocks.
Herladen, niet herstarten
Pas de nieuwe configuratie toe:
sudo systemctl reload nginx
Waarom reload in plaats van restart? Een reload stuurt een signaal naar Nginx om de configuratiebestanden opnieuw in te lezen. Bestaande verbindingen worden normaal afgerond. Een restart beëindigt het proces en start een nieuw proces, waardoor alle actieve verbindingen verbroken worden. In productie altijd herladen.
Controleer of het herladen gelukt is:
sudo systemctl status nginx
Let op: zoek naar active (running) en controleer de tijdstempel op de "Main PID"-regel. Die zou niet veranderd moeten zijn (wat een reload bevestigt, geen restart).
Een site deactiveren
Om een site offline te halen zonder de configuratie te verwijderen:
sudo rm /etc/nginx/sites-enabled/site-two.com
sudo nginx -t && sudo systemctl reload nginx
Het configuratiebestand blijft in sites-available/. Activeer het op elk moment opnieuw door de symlink opnieuw aan te maken.
Hoe verifieer je of je server blocks werken?
Open geen browser. Gebruik op een headless VPS curl met de Host-header om aanvragen van elk domein te simuleren:
curl -H "Host: site-one.com" http://localhost
Verwachte uitvoer:
<h1>Site One</h1>
curl -H "Host: site-two.com" http://localhost
Verwachte uitvoer:
<h1>Site Two</h1>
Dit werkt zelfs voordat DNS is doorgevoerd, omdat je Nginx direct vertelt welk domein je wilt via de Host-header.
Zodra DNS is doorgevoerd, test je vanaf je lokale machine (niet de server):
curl http://site-one.com
curl http://site-two.com
Elke aanvraag zou de juiste testpagina moeten teruggeven.
Hoe bepaalt Nginx welk server block een aanvraag afhandelt?
Nginx matcht inkomende aanvragen aan server blocks in een specifieke volgorde. Wanneer een aanvraag binnenkomt, filtert Nginx eerst server blocks op de listen-directive (IP en poort), daarna matcht het de Host-header tegen server_name-waarden.
Wat is de matchvolgorde voor server_name?
De matchvolgorde is vast en kan niet worden gewijzigd door de volgorde van configuratiebestanden:
| Prioriteit | Patroontype | Voorbeeld | Wanneer gebruikt |
|---|---|---|---|
| 1 (hoogste) | Exacte naam | site-one.com |
Altijd als eerste geprobeerd. Snelst (hash lookup). |
| 2 | Langste wildcard prefix | *.site-one.com |
Matcht www.site-one.com, api.site-one.com |
| 3 | Langste wildcard suffix | mail.* |
Matcht mail.site-one.com, mail.site-two.com |
| 4 | Eerste matchende regex | ~^www\d+\.example\.com$ |
Geëvalueerd in volgorde van het configuratiebestand. Eerste match wint. |
| 5 (laagste) | default_server |
N/A | Fallback als niets anders matcht. |
Belangrijke punten:
- Exacte namen worden altijd als eerste gecontroleerd, ongeacht waar het server block verschijnt in de configuratie.
- Wildcard namen kunnen alleen een
*hebben aan het begin of einde, op een puntgrens.w*.example.comis ongeldig. - Regex-patronen beginnen met
~en worden getest in de volgorde waarin ze verschijnen in configuratiebestanden. Eerste match wint. Gebruik ze spaarzaam, want het is het traagste matchtype. - Als niets matcht en er is geen
default_serveringesteld, gebruikt Nginx het eerste server block in de volgorde van configuratiebestanden als standaard. Dit is een veelvoorkomende bron van verwarring.
Wat doet de default_server-directive?
De default_server-parameter op de listen-directive vertelt Nginx welk server block aanvragen afhandelt als geen server_name overeenkomt. Zonder dit kiest Nginx stilzwijgend het eerste server block dat geladen is voor die poort. Dit betekent dat een verkeerd geconfigureerd domein of een bot die je IP-adres scant, een van je echte sites te zien krijgt.
Maak een catch-all server block aan dat ongematchte aanvragen weggooit:
sudo nano /etc/nginx/sites-available/00-catch-all
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
Wat dit doet:
default_servermarkeert dit block als fallback voor poort 80.server_name _is een conventie voor "geen geldige naam." Het underscore-teken is niet speciaal voor Nginx; het matcht gewoon nooit een echte hostnaam.return 444is een niet-standaard Nginx-code die de verbinding sluit zonder een antwoord te sturen. Bots die je IP scannen krijgen niets terug. Geen headers, geen body, geen informatie over welke software je gebruikt.
Activeer en pas toe:
sudo ln -s /etc/nginx/sites-available/00-catch-all /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
De bestandsnaam begint met 00- zodat het bovenaan staat in mapoverzichten. Dit heeft geen effect op het Nginx-gedrag (de default_server-directive bepaalt de selectie, niet de bestandsvolgorde), maar het maakt de configuratie gemakkelijker te lezen voor mensen.
Test de catch-all door een domein aan te vragen dat niet overeenkomt met een server block:
curl -v -H "Host: not-my-domain.com" http://localhost
Je zou Empty reply from server moeten zien, omdat Nginx de verbinding heeft gesloten zonder antwoord.
Hoe stel je logging per site in?
Elk server block in deze handleiding bevat al per-site log-directives. Per-site logs laten je één site debuggen zonder het verkeer van al je andere domeinen te moeten doorzoeken. De logpaden zijn ingesteld in elk server block:
access_log /var/log/nginx/site-one.com.access.log;
error_log /var/log/nginx/site-one.com.error.log;
Volg de logs in realtime:
sudo tail -f /var/log/nginx/site-one.com.access.log
Of gebruik journalctl voor de logs van het Nginx-hoofdproces (opstartfouten, herlaadfouten):
journalctl -u nginx -f
Nginx verwerkt logrotatie automatisch via /etc/logrotate.d/nginx. Het standaardbeleid roteert logs dagelijks en bewaart 14 dagen. Geen extra configuratie nodig.
Wat zijn veelvoorkomende server block-problemen en oplossingen?
| Symptoom | Oorzaak | Oplossing |
|---|---|---|
| Standaard "Welcome to Nginx"-pagina verschijnt voor alle domeinen | default-symlink staat nog in sites-enabled/ |
sudo rm /etc/nginx/sites-enabled/default && sudo systemctl reload nginx |
| Verkeerde site geserveerd voor een domein | Dubbele server_name in verschillende blocks, of geen exacte match gevonden |
Voer `sudo nginx -T |
Fout could not build server_names_hash |
Domeinnamen te lang voor de standaard hash bucket | Voeg server_names_hash_bucket_size 128; toe in het http {}-block in /etc/nginx/nginx.conf |
| Wijzigingen hebben geen effect na het bewerken van de configuratie | Vergeten te herladen | sudo nginx -t && sudo systemctl reload nginx |
bind() to 0.0.0.0:80 failed |
Een ander proces (Apache, oude Nginx) gebruikt poort 80 | `sudo ss -tlnp |
| Symlink aangemaakt maar site laadt nog niet | Symlink wijst naar verkeerd pad (relatief in plaats van absoluut) | Verwijder en herstel: sudo ln -sf /etc/nginx/sites-available/site-one.com /etc/nginx/sites-enabled/ |
Debuggen met nginx -T
Wanneer een site zich niet gedraagt zoals verwacht, dump de volledige samengevoegde configuratie:
sudo nginx -T 2>&1 | grep -A 5 "server_name"
Dit toont elk server block met zijn server_name-waarde, zodat je precies kunt zien wat Nginx geladen heeft en in welke volgorde. Het lost alle include-directives op, zodat je de werkelijke configuratie ziet, niet alleen de bestanden op schijf.
Volgende stappen
Je server blocks serveren nu meerdere domeinen via HTTP. De volgende stap is TLS-certificaten toevoegen zodat deze sites via HTTPS worden geserveerd.
Voor een breder overzicht van Nginx beheren op een VPS, zie de bovenliggende handleiding.
Copyright 2026 Virtua.Cloud. Alle rechten voorbehouden. Deze inhoud is een origineel werk van het Virtua.Cloud-team. Reproductie, herpublicatie of herdistributie zonder schriftelijke toestemming is verboden.
Klaar om het zelf te proberen?
Deploy uw eigen server in seconden. Linux, Windows of FreeBSD.
Bekijk VPS-aanbod