Hospedagem Virtual Nginx: Hospedando Múltiplos Sites em um Único Servidor

Desbloqueie o poder dos hosts virtuais Nginx (blocos de servidor) para hospedar eficientemente múltiplos sites ou subdomínios em um único servidor. Este guia fornece um tutorial abrangente e passo a passo, cobrindo configuração de diretórios, criação de arquivos de configuração, ativação de blocos de servidor e teste do Nginx. Aprenda as melhores práticas para subdomínios, blocos de servidor padrão, integração HTTPS e logs dedicados. Exemplos práticos e dicas essenciais de solução de problemas ajudarão você a dominar a hospedagem multi-site Nginx, otimizando o uso de recursos e simplificando o gerenciamento do servidor web.

Hospedagem Virtual Nginx: Hospedando Múltiplos Sites em um Único Servidor

Executar vários sites pequenos a partir de um único servidor é uma tarefa comum do Nginx. Você pode ter um site corporativo, um site de documentação, um aplicativo de staging e um portal do cliente, todos no mesmo servidor. O Nginx os separa com blocos server. Usuários do Apache costumam chamar a mesma ideia de hosts virtuais, então você verá ambos os termos em tutoriais e painéis de hospedagem.

A parte importante é simples: o Nginx analisa a porta, o endereço IP e o cabeçalho Host, e então escolhe o bloco server correspondente. Se o site errado carregar, o problema geralmente não é misterioso. Geralmente é um registro DNS ausente, um erro de digitação em server_name, um servidor padrão capturando a requisição ou dois arquivos reivindicando o mesmo nome.

Entendendo os Blocos de Servidor Nginx (Hosts Virtuais)

Em sua essência, um bloco de servidor Nginx é uma diretiva de configuração definida dentro do arquivo de configuração do Nginx (nginx.conf ou arquivos incluídos). Cada bloco server define a configuração para um host virtual específico, ditando como o Nginx deve responder a requisições para um domínio ou conjunto de domínios específico. O Nginx usa a diretiva listen para especificar o endereço IP e a porta em que deve escutar, e a diretiva server_name para identificar quais nomes de domínio ou nomes de host este bloco de servidor deve atender.

Quando uma requisição chega, o Nginx examina o cabeçalho Host da requisição HTTP e o compara com as diretivas server_name de seus blocos de servidor configurados. Em seguida, ele serve o conteúdo definido no bloco de servidor correspondente. Se nenhum server_name corresponder, o Nginx geralmente recai para o bloco de servidor padrão (o primeiro bloco server ou um explicitamente marcado como default_server).

Pré-requisitos

Antes de começar, certifique-se de ter o seguinte:

  1. Nginx Instalado: O Nginx deve estar instalado e em execução no seu servidor. Se não estiver, você geralmente pode instalá-lo através do gerenciador de pacotes do seu sistema (por exemplo, sudo apt update && sudo apt install nginx no Ubuntu/Debian, sudo yum install nginx no CentOS/RHEL).
  2. Nomes de Domínio: Você precisa de pelo menos dois nomes de domínio (por exemplo, exemplo1.com e exemplo2.com) ou subdomínios (por exemplo, blog.exemplo.com e app.exemplo.com) que deseja hospedar. Os registros DNS A/AAAA desses domínios devem apontar para o endereço IP público do seu servidor.
  3. Estrutura de Diretórios Básica: Um plano de onde os arquivos do seu site residirão. Uma prática comum é /var/www/seu-dominio.com/html.
  4. Privilégios Sudo: Você precisará de acesso sudo para modificar os arquivos de configuração do Nginx.

Guia de Configuração Passo a Passo

Vamos configurar dois hosts virtuais: exemplo1.com e exemplo2.com.

Passo 1: Criar Estrutura de Diretórios para os Sites

Primeiro, crie diretórios raiz para cada um dos seus sites. É aqui que seus arquivos HTML, CSS, JavaScript e outros arquivos estáticos serão armazenados. Um local comum é /var/www/.

sudo mkdir -p /var/www/exemplo1.com/html
sudo mkdir -p /var/www/exemplo2.com/html

# Defina a propriedade para seu usuário (substitua $USER pelo seu nome de usuário) para permitir edição
sudo chown -R $USER:$USER /var/www/exemplo1.com/html
sudo chown -R $USER:$USER /var/www/exemplo2.com/html

# Defina permissões de leitura para o servidor web
sudo chmod -R 755 /var/www

Em seguida, crie um arquivo index.html simples em cada diretório para testar a configuração:

Para /var/www/exemplo1.com/html/index.html:

<!-- /var/www/exemplo1.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Bem-vindo ao Exemplo1.com!</title>
</head>
<body>
    <h1>Sucesso! Este é o Exemplo1.com.</h1>
    <p>Este host virtual está funcionando corretamente.</p>
</body>
</html>

Para /var/www/exemplo2.com/html/index.html:

<!-- /var/www/exemplo2.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Bem-vindo ao Exemplo2.com!</title>
</head>
<body>
    <h1>Sucesso! Este é o Exemplo2.com.</h1>
    <p>Este host virtual também está funcionando!</p>
</body>
</html>

Passo 2: Criar Arquivos de Configuração do Bloco de Servidor Nginx

O Nginx normalmente carrega as configurações do bloco de servidor a partir de arquivos no diretório /etc/nginx/sites-enabled/. Esses arquivos geralmente são links simbólicos para configurações armazenadas em /etc/nginx/sites-available/. Essa separação permite armazenar configurações que ainda não estão ativas ou ativar/desativar sites facilmente.

Crie um novo arquivo de configuração para exemplo1.com:

sudo nano /etc/nginx/sites-available/exemplo1.com.conf

Adicione o seguinte conteúdo:

# /etc/nginx/sites-available/exemplo1.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/exemplo1.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name exemplo1.com www.exemplo1.com;

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

    access_log /var/log/nginx/exemplo1.com_access.log;
    error_log /var/log/nginx/exemplo1.com_error.log;
}

Explicação das Diretivas:

  • listen 80;: O Nginx escuta na porta 80 (HTTP padrão). listen [::]:80; é para IPv6.
  • root /var/www/exemplo1.com/html;: Especifica a raiz do documento para este bloco de servidor. O Nginx procurará arquivos dentro deste diretório.
  • index index.html ...;: Define o arquivo padrão que o Nginx deve servir quando um diretório é solicitado (por exemplo, quando alguém visita exemplo1.com/).
  • server_name exemplo1.com www.exemplo1.com;: Isso é crucial. Diz ao Nginx para responder a requisições para exemplo1.com ou www.exemplo1.com usando a configuração deste bloco de servidor.
  • location / { ... }: Um bloco que define como lidar com requisições para URIs específicas. try_files tenta servir um arquivo diretamente ($uri), depois um diretório ($uri/) e, finalmente, retorna um erro 404 Not Found.
  • access_log e error_log: Especifica arquivos de log separados para este site específico, o que é uma boa prática para depuração e análise mais fáceis.

Agora, crie um arquivo de configuração semelhante para exemplo2.com:

sudo nano /etc/nginx/sites-available/exemplo2.com.conf

Adicione o seguinte conteúdo:

# /etc/nginx/sites-available/exemplo2.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/exemplo2.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name exemplo2.com www.exemplo2.com;

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

    access_log /var/log/nginx/exemplo2.com_access.log;
    error_log /var/log/nginx/exemplo2.com_error.log;
}

Passo 3: Ativar Blocos de Servidor

Para ativar essas configurações, crie links simbólicos do diretório sites-available para o diretório sites-enabled. Isso informa ao Nginx para incluir esses arquivos quando ele iniciar.

sudo ln -s /etc/nginx/sites-available/exemplo1.com.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/exemplo2.com.conf /etc/nginx/sites-enabled/

Passo 4: Testar a Configuração do Nginx

É crucial testar sua configuração do Nginx em busca de erros de sintaxe antes de recarregar. Isso evita que o Nginx falhe ao reiniciar devido a um erro de digitação.

sudo nginx -t

Você deve ver uma saída semelhante a esta, indicando sucesso:

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

Se você vir algum erro, corrija-o nos respectivos arquivos de configuração e execute sudo nginx -t novamente até que passe.

Passo 5: Reiniciar o Nginx

Aplique a nova configuração reiniciando ou recarregando o Nginx. reload é geralmente preferido, pois permite que o Nginx carregue novas configurações sem interromper conexões ativas.

sudo systemctl reload nginx
# Ou, se o reload não funcionar ou para instalações novas:
sudo systemctl restart nginx

Passo 6: Atualizar Registros DNS

Certifique-se de que os registros DNS A para exemplo1.com, www.exemplo1.com, exemplo2.com e www.exemplo2.com apontem todos para o endereço IP do seu servidor Nginx. Sem entradas DNS corretas, seu navegador não saberá onde encontrar seus sites.

Assim que a propagação do DNS for concluída (o que pode levar de alguns minutos a várias horas), você poderá visitar http://exemplo1.com e http://exemplo2.com em seu navegador web e ver as respectivas páginas index.html.

Cenários Avançados e Melhores Práticas

Hospedando Subdomínios

Hospedar subdomínios (por exemplo, blog.exemplo.com, loja.exemplo.com) funciona exatamente como hospedar domínios separados. Você apenas define um novo bloco de servidor com o subdomínio como server_name.

Exemplo para blog.exemplo.com:

# /etc/nginx/sites-available/blog.exemplo.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/blog.exemplo.com/html;
    index index.html;

    server_name blog.exemplo.com;

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

Lembre-se de criar o diretório (/var/www/blog.exemplo.com/html), criar um index.html, criar o link simbólico e recarregar o Nginx.

O Bloco de Servidor Padrão

É uma boa prática ter um bloco de servidor padrão que captura requisições para nomes de domínio que não correspondem a nenhuma outra diretiva server_name em seu servidor. Isso evita que requisições desconhecidas sejam servidas pelo primeiro host virtual que o Nginx encontrar, ou permite que você sirva uma página genérica de "site não encontrado".

Normalmente, o primeiro bloco server em seu nginx.conf ou sites-enabled é implicitamente o padrão. Você pode definir explicitamente um usando default_server:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;
    # O sublinhado `_` é um nome de domínio inexistente que nunca corresponderá a uma requisição real.
    # Você também pode usar localhost.

    root /var/www/default_site/html;
    index index.html;

    location / {
        return 444; # Retorna um erro 444 específico do Nginx (sem resposta) para hosts desconhecidos
        # Ou, sirva uma página de destino genérica:
        # try_files $uri $uri/ =404;
    }
}

Aviso: Se você definir um bloco default_server, certifique-se de que apenas um bloco server em uma determinada porta listen tenha o sinalizador default_server, caso contrário, o Nginx registrará um aviso.

Protegendo Hosts Virtuais com HTTPS (SSL/TLS)

Para sites de produção, habilitar HTTPS é essencial. Isso envolve obter um certificado SSL/TLS (por exemplo, via Let's Encrypt usando Certbot) e configurar o Nginx para escutar na porta 443 com o certificado.

Um bloco de servidor HTTPS típico se parece com isso (após obter os certificados):

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name exemplo1.com www.exemplo1.com;

    root /var/www/exemplo1.com/html;
    index index.html;

    ssl_certificate /etc/letsencrypt/live/exemplo1.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exemplo1.com/privkey.pem;

    # Inclua outras configurações SSL (cifras, protocolos, etc.)
    include /etc/nginx/snippets/ssl-params.conf;

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

# Opcional: Redirecionamento HTTP para HTTPS para este domínio
server {
    listen 80;
    listen [::]:80;
    server_name exemplo1.com www.exemplo1.com;
    return 301 https://$host$request_uri;
}

É comum ter um bloco de servidor HTTP separado cujo único propósito é redirecionar todo o tráfego para sua contraparte HTTPS.

Se você usar o Certbot, ele pode criar ou editar esses blocos para você. Isso é conveniente, mas você ainda deve ler o arquivo resultante. Ferramentas de certificado automatizadas às vezes adicionam lógica de redirecionamento em um lugar que você não teria escolhido, e redirecionamentos duplicados podem dificultar a solução de problemas.

Logging para Cada Site

Conforme mostrado nos exemplos, dedicar arquivos access_log e error_log separados para cada host virtual é uma boa prática. Isso torna significativamente mais fácil depurar problemas e analisar o tráfego de sites individuais sem ter que vasculhar logs combinados.

Estrutura de Arquivos de Configuração

Para implantações maiores, considere organizar seus arquivos de configuração do Nginx assim:

  • nginx.conf: Configuração principal, inclui conf.d/*.conf e sites-enabled/*.
  • conf.d/: Configurações gerais de todo o servidor (por exemplo, Gzip, cache).
  • snippets/: Trechos de configuração Nginx reutilizáveis (por exemplo, parâmetros SSL, blocos location comuns).
  • sites-available/: Blocos server individuais para cada site.
  • sites-enabled/: Links simbólicos para configurações ativas em sites-available/.

Solução de Problemas Comuns

  • Erro 403 Proibido: Isso geralmente significa que o Nginx não tem acesso de leitura aos arquivos ou diretórios do seu site. Verifique novamente as permissões de arquivos e diretórios (por exemplo, sudo chmod -R 755 /var/www/seu-dominio.com/html e certifique-se de que o usuário do Nginx, normalmente www-data ou nginx, possa lê-los).
  • Erro 404 Não Encontrado: Verifique se a diretiva root em seu bloco de servidor aponta para o diretório correto e se seu arquivo index.html existe nesse local. Além disso, certifique-se de que try_files está configurado corretamente.
  • Site Errado Está Carregando: Isso geralmente indica um problema com a diretiva server_name. Certifique-se de que o server_name corresponda exatamente ao nome de domínio que você está tentando acessar (incluindo www. ou subdomínios). Além disso, verifique seus registros DNS.
  • Nginx Falha ao Iniciar/Recarregar: Sempre use sudo nginx -t para testar sua configuração antes de tentar recarregar ou reiniciar o Nginx. As mensagens de erro apontarão a linha e o arquivo onde ocorreu o erro de sintaxe.
  • Problemas de DNS: Se você pode acessar seu site pelo endereço IP, mas não pelo nome de domínio, é quase certamente um problema de DNS. Use dig ou nslookup para verificar se os registros A do seu domínio apontam para o IP correto do servidor.

Testando Antes do DNS Estar Pronto

Você não precisa esperar pelo DNS público para testar o lado do Nginx. Você pode enviar uma requisição com um cabeçalho Host personalizado:

curl -H "Host: exemplo1.com" http://203.0.113.10/
curl -H "Host: exemplo2.com" http://203.0.113.10/

Substitua 203.0.113.10 pelo IP do seu servidor. Se cada comando retornar a página de teste correta, a correspondência do bloco de servidor está funcionando. Se ambos os comandos retornarem a mesma página, verifique se ambos os arquivos estão ativados, se server_name está correto e se um bloco padrão está capturando a requisição.

Para HTTPS, o teste é um pouco diferente porque o TLS usa SNI antes que o cabeçalho HTTP Host seja processado:

curl --resolve exemplo1.com:443:203.0.113.10 https://exemplo1.com/

Esse comando diz ao curl para se conectar ao IP do seu servidor enquanto ainda usa exemplo1.com para TLS e HTTP. É uma das maneiras mais rápidas de testar um novo host virtual HTTPS antes de alterar o DNS.

Um Padrão Multi-Site Sustentável

Para alguns sites estáticos, os exemplos acima são suficientes. Quando você hospedar vários aplicativos, repita menos e centralize apenas as partes que são genuinamente compartilhadas. Por exemplo, coloque cabeçalhos de segurança comuns, compressão e parâmetros SSL em snippets, mas mantenha o root, server_name, upstream e logs de cada site visíveis em seu próprio arquivo.

Evite copiar um bloco de produção grande de um domínio para outro sem ler cada linha. É assim que erros de server_name, caminhos de certificado errados e arquivos de log compartilhados se infiltram. Uma lista de verificação prática de revisão é curta:

  • O server_name inclui todos os nomes de host que os usuários digitarão?
  • O root ou proxy_pass aponta para este site, não para o anterior?
  • Os logs de acesso e erro estão separados o suficiente para depurar este site sozinho?
  • O nginx -t passa antes do reload?
  • O curl -H "Host: ..." ou curl --resolve retorna o site esperado?

Notas Finais

Os hosts virtuais Nginx são confiáveis quando cada site tem um bloco de servidor claro, um server_name correto e um fallback padrão previsível. Mantenha os arquivos simples. Teste cada alteração antes de recarregar. Use logs dedicados quando os sites forem importantes. A maioria dos problemas multi-site do Nginx se torna fácil de resolver quando você pode provar se DNS, TLS/SNI ou a correspondência do bloco de servidor foi a parte que falhou.