Como o Apache interpreta a configuração (visão mental do “modelo”)
O Apache processa a configuração como um conjunto de diretivas aplicadas em contextos. Cada diretiva só é válida em certos contextos (por exemplo, algumas só funcionam no contexto global, outras dentro de <VirtualHost>, outras dentro de <Directory> etc.). O comportamento final de uma requisição é o resultado da combinação (e, às vezes, do conflito) entre diretivas aplicadas em camadas.
Uma forma prática de pensar é separar em dois grandes blocos:
- ServerConfig (global): diretivas fora de qualquer bloco. Afetam o servidor como um todo (ou definem padrões).
- VirtualHost: diretivas dentro de
<VirtualHost>. Afetam apenas aquele host virtual (um site).
Além disso, existem contextos que refinam o comportamento para partes do sistema de arquivos ou da URL:
<Directory>: baseado em caminho no sistema de arquivos (ex.:/var/www/site/public).<Files>e<FilesMatch>: baseado no nome do arquivo (ex.:.env,*.php).<Location>e<LocationMatch>: baseado na URL (ex.:/admin), independente de onde isso está no disco.
Ordem de leitura vs. ordem de aplicação
O Apache lê a configuração na ordem em que os arquivos são incluídos (via Include/IncludeOptional), mas a aplicação das diretivas ocorre conforme o contexto e o tipo de diretiva. Por isso, “estar mais embaixo no arquivo” nem sempre significa “ganhar”. O que manda é: contexto + regras de mesclagem/precedência da diretiva.
Contextos e quando usar cada um
1) ServerConfig (global)
Use para padrões do servidor, módulos, logs globais, e valores que devem valer para todos os sites (a menos que sejam sobrescritos onde permitido).
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
# Contexto global (ServerConfig) — exemplo conceitual, não copie sem adaptar Paths/ports2) VirtualHost
Use para separar sites. Dentro dele você define ServerName, DocumentRoot, logs do site, e regras específicas daquele domínio.
<VirtualHost *:80> # contexto VirtualHost (site A) </VirtualHost> <VirtualHost *:80> # contexto VirtualHost (site B) </VirtualHost>3) Directory (sistema de arquivos)
Use para controlar permissões e opções por diretório real no disco. É o contexto mais comum para Require, Options e AllowOverride.
<Directory "/var/www/site/public"> Require all granted </Directory>4) Files / FilesMatch (nome do arquivo)
Use para proteger arquivos específicos (por nome ou regex), mesmo que estejam dentro de diretórios liberados.
<Files ".env"> Require all denied </Files>5) Location / LocationMatch (URL)
Use quando a regra deve seguir a URL, e não o caminho no disco (ex.: endpoints de aplicação, rotas “virtuais”, proxies). Importante: <Location> pode afetar conteúdo que nem existe como arquivo, então use com cuidado.
<Location "/admin"> Require ip 192.0.2.10 </Location>Como o Apache decide “qual VirtualHost atende”
Quando chega uma requisição, o Apache escolhe o <VirtualHost> com base em:
- IP:porta que recebeu a conexão (ex.:
*:80,192.0.2.20:80). - Host header (ex.:
Host: exemplo.com) comparado comServerName/ServerAlias.
Se não houver correspondência, ele usa o primeiro VirtualHost definido para aquele IP:porta como “default” (comportamento comum em name-based vhosts).
Exemplo progressivo: dois sites na mesma porta
# Arquivo incluído pelo Apache (ordem importa para o “default”) <VirtualHost *:80> ServerName site-a.local DocumentRoot "/var/www/site-a/public" ErrorLog "/var/log/apache2/site-a-error.log" CustomLog "/var/log/apache2/site-a-access.log" combined </VirtualHost> <VirtualHost *:80> ServerName site-b.local DocumentRoot "/var/www/site-b/public" ErrorLog "/var/log/apache2/site-b-error.log" CustomLog "/var/log/apache2/site-b-access.log" combined </VirtualHost>Se uma requisição chegar com Host: site-b.local, o segundo bloco atende. Se chegar com um host desconhecido (ou sem Host em HTTP/1.0), o primeiro tende a ser usado como padrão.
Mesclagem e conflitos: como o resultado final é composto
Nem toda diretiva “sobrescreve” outra do mesmo jeito. Existem diretivas que:
- Substituem (a última definição aplicável vence).
- Acumulam (várias entradas se somam, como múltiplos
Header addou múltiplosAlias). - Mesclam por regra própria (ex.: controle de acesso com
Requirepode combinar condições dependendo de como você estrutura os blocos e módulos).
Mesmo sem decorar todas as regras, dá para depurar seguindo um método: (1) identifique o VirtualHost escolhido, (2) identifique o caminho real do arquivo (filesystem) e a URL, (3) liste quais blocos <Directory>, <Files> e <Location> podem se aplicar, (4) verifique se alguma diretiva é “acumulativa” ou “substitutiva”.
Exemplo 1: conflito de DocumentRoot (substituição por contexto)
DocumentRoot é típico de VirtualHost. Um DocumentRoot global pode existir como padrão, mas o do VirtualHost é o que vale para aquele site.
# Global (ServerConfig) DocumentRoot "/var/www/default" <VirtualHost *:80> ServerName app.local DocumentRoot "/var/www/app/public" </VirtualHost>Para Host: app.local, o conteúdo vem de /var/www/app/public, não do global.
Exemplo 2: Directory mais específico tende a refinar o menos específico
É comum ter um bloco amplo e outro mais específico. O mais específico (caminho mais profundo) normalmente refina o comportamento para aquele subdiretório.
<VirtualHost *:80> ServerName exemplo.local DocumentRoot "/var/www/exemplo/public" <Directory "/var/www/exemplo"> Require all denied </Directory> <Directory "/var/www/exemplo/public"> Require all granted </Directory> </VirtualHost>Resultado esperado: o diretório public fica acessível, enquanto o restante de /var/www/exemplo permanece negado (útil para evitar exposição de diretórios fora do DocumentRoot).
Exemplo 3: Files pode “fechar” um arquivo dentro de um diretório liberado
<VirtualHost *:80> ServerName exemplo.local DocumentRoot "/var/www/exemplo/public" <Directory "/var/www/exemplo/public"> Require all granted </Directory> <Files ".env"> Require all denied </Files> </VirtualHost>Resultado esperado: o site funciona, mas uma tentativa de acessar /.env deve ser negada (se o arquivo estiver sob o escopo atendido).
Exemplo 4: Location atua pela URL (e pode divergir do Directory)
Compare: <Directory> olha para o caminho no disco; <Location> olha para a URL. Se sua aplicação mapeia /admin para um front controller (ex.: index.php), o arquivo real pode ser sempre o mesmo, mas a URL muda.
<VirtualHost *:80> ServerName exemplo.local DocumentRoot "/var/www/exemplo/public" <Directory "/var/www/exemplo/public"> Require all granted </Directory> <Location "/admin"> Require ip 192.0.2.10 </Location> </VirtualHost>Resultado esperado: qualquer URL começa liberada, mas /admin exige IP permitido, mesmo que o arquivo servido seja o mesmo do restante do site.
Passo a passo prático: depurar “por que esta URL está/ não está acessível?”
Passo 1 — Descobrir qual VirtualHost está atendendo
Verifique a combinação de IP:porta e o Host da requisição. Em seguida, localize o bloco <VirtualHost ...> com ServerName/ServerAlias correspondente. Se não houver, o primeiro VirtualHost daquele IP:porta tende a ser o default.
Passo 2 — Mapear URL para caminho (quando aplicável)
Para conteúdo estático, a URL geralmente mapeia para DocumentRoot + caminho. Para aplicações, pode haver reescritas internas, mas ainda assim você consegue identificar o diretório base e quais blocos <Directory> podem atingir o caminho físico final.
Passo 3 — Listar blocos que podem se aplicar
- Directory: quais blocos cobrem o caminho? (ex.:
/var/www/exemploe/var/www/exemplo/public). - Files: existe algum bloco para o nome do arquivo requisitado?
- Location: a URL bate em algum
<Location>?
Passo 4 — Procurar diretivas “decisivas”
Para acesso, procure principalmente por Require (e blocos onde ele aparece). Para comportamento de diretório, procure Options e AllowOverride. Para logs, procure ErrorLog/CustomLog no VirtualHost.
Atividade: “prever o resultado” antes de testar
Leia cada configuração e responda: (1) qual VirtualHost atende Host: ..., (2) a URL será permitida ou negada, (3) qual regra foi determinante. Só depois compare com o comportamento real no seu ambiente.
Cenário A
<VirtualHost *:80> ServerName loja.local DocumentRoot "/var/www/loja/public" <Directory "/var/www/loja"> Require all denied </Directory> <Directory "/var/www/loja/public"> Require all granted </Directory> </VirtualHost>- Preveja: acessar
http://loja.local/é permitido ou negado? - Preveja: acessar um arquivo em
/var/www/loja/segredo.txt(fora dopublic) via URL seria possível?
Cenário B
<VirtualHost *:80> ServerName intranet.local DocumentRoot "/var/www/intra/public" <Directory "/var/www/intra/public"> Require all granted </Directory> <Location "/admin"> Require all denied </Location> </VirtualHost>- Preveja:
http://intranet.local/funciona? - Preveja:
http://intranet.local/adminretorna qual tipo de resultado (permitido/negado)?
Cenário C
<VirtualHost *:80> ServerName app.local DocumentRoot "/var/www/app/public" <Directory "/var/www/app/public"> Require all granted </Directory> <FilesMatch "\.(bak|old)$"> Require all denied </FilesMatch> </VirtualHost>- Preveja:
/index.htmlé permitido? - Preveja:
/config.php.baké permitido?
Cenário D (VirtualHost default)
<VirtualHost *:80> ServerName primeiro.local DocumentRoot "/var/www/primeiro" </VirtualHost> <VirtualHost *:80> ServerName segundo.local DocumentRoot "/var/www/segundo" </VirtualHost>- Preveja: se chegar uma requisição com
Host: desconhecido.local, qualDocumentRoottende a ser usado?
Exemplos curtos de “armadilhas” comuns de contexto
1) Tentar controlar URL com Directory
<Directory> não casa com URL, casa com caminho no disco. Se você escrever <Directory "/admin">, isso não protege http://site/admin (a menos que exista um diretório real /admin no filesystem e ele seja o caminho atendido).
2) Proteger por Location e esquecer que a aplicação reescreve tudo
Se sua aplicação reescreve rotas (ex.: tudo cai em index.php), proteger apenas um arquivo específico com <Files> pode não surtir efeito para uma rota. Nesses casos, <Location> costuma ser mais adequado para rotas.
3) Conflitos por múltiplos Includes
Se o mesmo VirtualHost ou diretiva aparece em mais de um arquivo incluído, você pode ter comportamento inesperado. Uma técnica de depuração é procurar definições duplicadas e garantir que cada site tenha um único bloco <VirtualHost> bem definido.
Tabela rápida: qual contexto escolher?
| Objetivo | Contexto recomendado | Base de correspondência |
|---|---|---|
| Configurar um site/domínio | <VirtualHost> | Host/IP:porta |
| Permitir/negar acesso a uma pasta real | <Directory> | Filesystem |
| Bloquear arquivos sensíveis por nome/extensão | <Files>/<FilesMatch> | Nome do arquivo |
| Restringir uma rota/endpoint | <Location>/<LocationMatch> | URL |
| Definir padrões globais | ServerConfig | Servidor inteiro |