Eu também me deparei com essa pergunta pesquisando no Google sobre apache2 dynamic vhost fallback e a resposta de Luc me ajudou muito na solução do meu problema, mas ainda quero mostrar o que fiz para alcançar meus objetivos, principalmente porque envolveu alguns trabalhos extras e porque acho que pode ser útil para futuros googlers ...
Os meus objetivos
- vhosting dinâmico para todos os domínios e subdomínios apontando para o meu VPS
foo.com
deve veicular o mesmo conteúdo que www.foo.com
- fallback para domínios desconhecidos para algum tipo de padrão
- fallback para subdomínios desconhecidos de
foo.com
a www.foo.com
, a menos que não www
esteja disponível, fallback para o padrão
DNS
Eu tenho alguns domínios (e todos os seus subdomínios) apontando para o meu VPS, por exemplo:
- foo.com
- bar.com
- foobar.com
Sistema de arquivo
Eu tenho os seguintes diretórios, os domínios contêm diretórios com os nomes dos subdomínios disponíveis, o diretório www é necessário, mas a configuração deve ser capaz de lidar com a situação em que não está presente. Localhost é usado como fallback padrão:
/var
/www
/localhost
/foo.com
/www
/bar
/bar.com
/foo
Testes
Traduzindo meus objetivos em casos testáveis:
- foo.com deve ser veiculado em foo.com/www
- www.foo.com deve ser veiculado em foo.com/www
- bar.foo.com deve ser veiculado em foo.com/bar
- foo.foo.com deve ser veiculado em foo.com/www (foo.com/foo não existe)
- bar.com deve ser veiculado no localhost (bar.com/www não existe)
- www.bar.com deve ser veiculado no localhost (bar.com/www não existe)
- foo.bar.com deve ser veiculado em bar.com/foo
- bar.bar.com deve ser veiculado no localhost (bar.com/bar não existe)
- foobar.com deve ser veiculado no localhost (foobar.com não existe)
- www.foobar.com deve ser veiculado no localhost (foobar.com não existe)
- foo.foobar.com deve ser veiculado a partir do host local (foobar.com não existe)
A solução
Isto usa: mod_rewrite
, mod_proxy_http
e é claro mod_vhost_alias
.
ServerName my.domain
ServerAdmin admin@my.domain
<VirtualHost *:80>
ServerName localhost
VirtualDocumentRoot /var/www/localhost
</VirtualHost>
<VirtualHost *:80>
ServerName sub.domain
ServerAlias *.*.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3 !-d
RewriteRule (.*) http://localhost/$1 [P]
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteCond /var/www/%2.%3/www !-d
RewriteRule (.*) http://localhost/$1 [P]
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteRule (.*) http://%2.%3/$1 [P]
</VirtualHost>
<VirtualHost *:80>
ServerName bare.domain
ServerAlias *.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/www
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)$ [NC]
RewriteCond /var/www/%1.%2 !-d [OR]
RewriteCond /var/www/%1.%2/www !-d
RewriteRule (.*) http://localhost/$1 [P]
</VirtualHost>
Como é que isso funciona? Existem três hosts virtuais definidos:
localhost
O host local serve como padrão. Todas as solicitações que não são resolvíveis são atendidas pelo host local. A configuração de um link simbólico do host local para qualquer um dos seus domínios é como configurar o site como padrão.
sub.domínio
O sub.domain vhost está recebendo todas as solicitações no formato de *.*.*
. Por padrão, todas as solicitações são atendidas /domain.com/sub
conforme definido por VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
.
cair pra trás:
O primeiro RewriteRule
cuida de domínios desconhecidos, por exemplo. domain.com
O diretório não existe, fazendo proxy do site localhost.
O segundo RewriteRule
também procura proxies para o host local quando domain.com/sub
os domain.com/www
diretórios e os não estão presentes.
Os terceiros RewriteRule
proxies para domain.com
quando domain.com/sub
não existe. Sabemos domain.com/www
que existe por causa do segundo bloco de reescrita.
bare.domain
O vhost bare.domain está recebendo as *.*
solicitações e as atende/domain.com/www
Aqui, o RewriteRule
proxy procurará o host local quando domain.com
ou domain.com/www
não existir.
^ $%. * !!!
Eu tive alguns problemas envolvendo minha cabeça em torno de todos aqueles $
e %
sinais no RewriteCond
e RewriteRule
por isso vou explicar sobre eles aqui:
ServerAlias *.*.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteRule (.*) http://%2.%3/$1 [P]
- Os
*
no ServerAlias
são apenas curingas.
- O
%n
no VirtualDocumentRoot
são do nome do documento de interpolação .
- O
%n
segundo RewriteCond
refere-se às seleções (.*)
do primeiro RewriteCond
, por exemplo. as partes do domínio solicitado.
- O
%n
no RewriteRule
fazer também.
- O
$1
no RewriteRule
refere-se à seleção (.*)
no início do RewriteRule
. Que captura tudo, desde o domínio até o ?
URL da solicitação. Qualquer string de consulta é automaticamente adicionada ao URL por mod_proxy
.