O que é um server block (virtual host)
No Nginx, um server (server block) define como o servidor deve responder a requisições para um conjunto específico de combinações de IP/porta (via listen) e nome de host (via server_name). Em termos práticos, é assim que você hospeda múltiplos sites/domínios no mesmo Nginx e também separa serviços por portas diferentes.
Um server block é escolhido em duas etapas: primeiro pelo socket (IP:porta) que recebeu a conexão; depois, dentro daquele socket, pelo Host (cabeçalho HTTP) comparado com server_name.
Diretiva listen: porta, IP e server padrão
listen na prática
A diretiva listen define em qual endereço/porta o Nginx vai aceitar conexões para aquele server block. Exemplos comuns:
listen 80;escuta na porta 80 em todos os IPs disponíveis (IPv4).listen 0.0.0.0:80;equivalente explícito para IPv4.listen 127.0.0.1:8080;escuta apenas localmente (útil para serviços internos).listen 192.168.10.10:80;escuta apenas em um IP específico.
Server padrão (default_server)
Para cada combinação de IP:porta, existe um server padrão: ele responde quando nenhum server_name casa com o Host recebido (ou quando o cliente não envia Host, em casos específicos).
Você define explicitamente com:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
listen 80 default_server;Se você não definir, o Nginx escolhe como padrão o primeiro server block carregado para aquele IP:porta (o que pode variar conforme a ordem dos arquivos incluídos).
Diretiva server_name: correspondência, curingas e precedência
Como o Nginx compara o Host com server_name
O Nginx seleciona o server block mais apropriado dentro do mesmo IP:porta usando regras de correspondência. Tipos comuns:
- Nome exato:
server_name example.com; - Múltiplos nomes:
server_name example.com www.example.com; - Curinga:
server_name *.example.com;(subdomínios) - Curinga no início:
server_name mail.*;(menos comum) - Regex:
server_name ~^(.+)\.example\.com$;(use com cuidado)
Precedência entre server blocks (resumo prático)
Dentro do mesmo listen (mesmo IP:porta), a escolha segue esta lógica geral:
- 1) Correspondência exata (ex.:
example.com) - 2) Curingas (ex.:
*.example.comemail.*) - 3) Regex (ex.:
~^api\.) - 4) Se nada casar: default_server (ou o primeiro carregado)
Na prática, prefira nomes exatos para domínios principais e use curingas apenas quando fizer sentido (por exemplo, muitos subdomínios com comportamento igual).
Passo a passo: múltiplos domínios na porta 80
Objetivo: servir dois sites diferentes no mesmo Nginx, ambos em HTTP na porta 80, diferenciados pelo Host.
1) Criar diretórios de site (exemplo com HTML simples)
sudo mkdir -p /var/www/site1/public /var/www/site2/publicecho 'SITE 1' | sudo tee /var/www/site1/public/index.htmlecho 'SITE 2' | sudo tee /var/www/site2/public/index.html2) Criar server blocks
Exemplo de dois server blocks distintos. Ajuste caminhos e domínios conforme seu cenário.
server { listen 80; server_name site1.local www.site1.local; root /var/www/site1/public; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 80; server_name site2.local www.site2.local; root /var/www/site2/public; index index.html; location / { try_files $uri $uri/ =404; }}Observação: o Nginx decide qual bloco usar com base no Host enviado pelo cliente. Se você acessar por IP sem Host adequado, pode cair no server padrão.
3) Definir um server padrão explícito para a porta 80
Crie um server block “catch-all” para evitar respostas inesperadas quando o Host não casar com nenhum domínio. Ele também ajuda a identificar rapidamente acessos errados.
server { listen 80 default_server; server_name _; return 444;}server_name _; é um padrão comum para indicar “não é um domínio real aqui”. O return 444; fecha a conexão sem resposta (útil para reduzir ruído). Se preferir, retorne 404:
return 404;Passo a passo: serviços internos em portas alternativas
Agora você quer expor um serviço interno (por exemplo, uma página de status, um app interno ou um endpoint administrativo) em uma porta diferente, sem misturar com os sites públicos na 80.
Exemplo A: serviço interno somente local (127.0.0.1:8081)
Esse server block só aceita conexões originadas do próprio servidor (bom para ser consumido por um reverse proxy local ou por ferramentas internas).
server { listen 127.0.0.1:8081; server_name internal.local; root /var/www/internal/public; location / { try_files $uri $uri/ =404; }}Mesmo que alguém tente acessar externamente, não conseguirá porque o Nginx não está escutando em interfaces públicas para essa porta.
Exemplo B: serviço interno na rede (192.168.10.10:8080) com restrição
Se você precisa que a rede interna acesse, escute no IP interno e restrinja por faixa:
server { listen 192.168.10.10:8080; server_name internal.lan; location / { allow 192.168.10.0/24; deny all; return 200 'OK - internal service'; }}Esse exemplo retorna uma resposta simples e restringe o acesso. Em um caso real, você apontaria para um root ou faria proxy para um serviço.
Como saber qual server block respondeu (testes com nginx -t e curl)
Validar sintaxe e consistência
Sempre valide antes de recarregar:
sudo nginx -tVocê deve ver algo como “syntax is ok” e “test is successful”. Se houver erro, o Nginx aponta arquivo e linha.
Inspecionar a resposta com curl e Host header
Para testar sem depender de DNS, envie o Host manualmente. Supondo que o Nginx esteja no IP 203.0.113.10:
curl -i -H 'Host: site1.local' http://203.0.113.10/curl -i -H 'Host: site2.local' http://203.0.113.10/Se você configurou um server padrão com return 444 ou return 404, teste também um Host desconhecido:
curl -i -H 'Host: naoexiste.local' http://203.0.113.10/Para testar a porta alternativa:
curl -i http://127.0.0.1:8081/Ou, se estiver em IP interno:
curl -i http://192.168.10.10:8080/Armadilhas comuns e como evitar
1) Dois server blocks com o mesmo listen e server_name
Se você duplicar a mesma combinação, um deles pode ficar “inacessível” na prática. Mantenha nomes únicos por IP:porta ou use uma estratégia clara (ex.: regex apenas quando necessário).
2) Esquecer o server padrão
Sem default_server, o “primeiro carregado” vira padrão e pode responder por hosts errados. Defina explicitamente um catch-all por porta exposta.
3) Curingas amplos demais
server_name *.example.com; pode capturar subdomínios que você pretendia tratar em outro bloco. Use nomes exatos para os principais e deixe o curinga para o restante, garantindo que o exato tenha precedência.
Padrão recomendado: um arquivo por site + template reutilizável
Estrutura por site (um arquivo por domínio)
Um padrão prático é ter um arquivo por site, com nomes claros. Exemplo de organização:
sites-available/site1.confsites-available/site2.confsites-available/internal.confsites-available/00-default.conf(catch-all)
E então habilitar via links/ includes conforme sua organização.
Template reutilizável de server block (HTTP 80)
Use este template como base e substitua as variáveis (domínio, raiz, logs). Ele já inclui um bloco simples e previsível.
server { listen 80; server_name DOMAIN www.DOMAIN; root /var/www/DOMAIN/public; index index.html index.htm; access_log /var/log/nginx/DOMAIN.access.log; error_log /var/log/nginx/DOMAIN.error.log; location / { try_files $uri $uri/ =404; }}Template de catch-all (default_server) por porta
server { listen 80 default_server; server_name _; access_log /var/log/nginx/default.access.log; error_log /var/log/nginx/default.error.log; return 444;}Template de serviço interno em porta alternativa
server { listen 127.0.0.1:8081; server_name internal.local; access_log /var/log/nginx/internal.access.log; error_log /var/log/nginx/internal.error.log; location / { return 200 'internal ok'; }}