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.coma www.foo.com, a menos que não wwwesteja 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_httpe é 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/subconforme definido por VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3.
cair pra trás:
O primeiro RewriteRulecuida de domínios desconhecidos, por exemplo. domain.comO diretório não existe, fazendo proxy do site localhost.
O segundo RewriteRuletambém procura proxies para o host local quando domain.com/subos domain.com/wwwdiretórios e os não estão presentes.
Os terceiros RewriteRuleproxies para domain.comquando domain.com/subnão existe. Sabemos domain.com/wwwque 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 RewriteRuleproxy procurará o host local quando domain.comou domain.com/wwwnão existir.
^ $%. * !!!
Eu tive alguns problemas envolvendo minha cabeça em torno de todos aqueles $e %sinais no RewriteConde RewriteRulepor 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 ServerAliassão apenas curingas.
- O
%nno VirtualDocumentRootsão do nome do documento de interpolação .
- O
%nsegundo RewriteCondrefere-se às seleções (.*)do primeiro RewriteCond, por exemplo. as partes do domínio solicitado.
- O
%nno RewriteRulefazer também.
- O
$1no RewriteRulerefere-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.