Server blocks no Nginx: virtual hosts, server_name e listen

Capítulo 4

Tempo estimado de leitura: 7 minutos

+ Exercício

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:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

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.com e mail.*)
  • 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/public
echo 'SITE 1' | sudo tee /var/www/site1/public/index.html
echo 'SITE 2' | sudo tee /var/www/site2/public/index.html

2) 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 -t

Você 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.conf
  • sites-available/site2.conf
  • sites-available/internal.conf
  • sites-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';    }}

Agora responda o exercício sobre o conteúdo:

Ao hospedar dois domínios diferentes no mesmo Nginx usando a mesma porta (listen 80), como o Nginx escolhe qual server block deve responder a uma requisição HTTP?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

O Nginx decide em duas etapas: primeiro pelo IP:porta do listen que recebeu a conexão e depois pelo Host comparado ao server_name. Se nada casar, responde o default_server (ou o primeiro carregado).

Próximo capitúlo

Servindo conteúdo estático com Nginx: root, index, try_files e cache de navegador

Arrow Right Icon
Capa do Ebook gratuito Nginx para Iniciantes: Servidor Web, Reverse Proxy e Balanceamento Básico
31%

Nginx para Iniciantes: Servidor Web, Reverse Proxy e Balanceamento Básico

Novo curso

13 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.