Também encontrei essa pergunta pesquisando o apache2 dynamic vhost fallback e a resposta de Luc me ajudou muito a resolver meu problema, mas ainda quero mostrar o que fiz para atingir meus objetivos, principalmente porque envolveu alguns trabalhos extras e porque acho que pode ser útil para futuros googlers ...
Minhas metas
- 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 de domínios desconhecidos para algum tipo de padrão
- fallback para subdomínios desconhecidos de
foo.com
to www.foo.com
, a menos que o www
não esteja disponível, o 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 arquivos
Eu tenho os seguintes diretórios, 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 servido em foo.com/www (foo.com/foo não existe)
-
bar.com deve ser servido a partir de localhost (bar.com/www não existe)
-
www.bar.com deve ser servido a partir de localhost (bar.com/www não existe)
-
foo.bar.com deve ser veiculado em bar.com/foo
-
bar.bar.com deve ser servido a partir de localhost (bar.com/bar não existe)
-
foobar.com deve ser servido a partir de localhost (foobar.com não existe)
-
www.foobar.com deve ser servido a partir de localhost (foobar.com não existe)
-
foo.foobar.com deve ser servido a partir de localhost (o foobar.com não existe)
A solução
Isso usa: mod_rewrite
, mod_proxy_http
e ofcourse mod_vhost_alias
.
ServerName my.domain
ServerAdmin [email protected]
<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 isso funciona? Existem três hosts virtuais definidos:
localhost
O localhost serve como padrão. Todas as solicitações que não são resolvidas são atendidas pelo host local. Configurar um link simbólico de localhost para qualquer um dos seus domínios é como configurar esse site como padrão.
sub.domain
O vhost sub.domain está recebendo todas as solicitações na forma de *.*.*
. Por padrão, todas as solicitações são atendidas a partir de /domain.com/sub
, conforme definido por VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
.
fallback:
O primeiro RewriteRule
cuida de domínios desconhecidos, por exemplo. O diretório domain.com
não existe, fazendo proxy no site do localhost.
O segundo RewriteRule
também faz proxy para o localhost quando os diretórios domain.com/sub
e domain.com/www
não estão presentes.
O terceiro RewriteRule
proxies para domain.com
quando domain.com/sub
não existe. Sabemos que domain.com/www
existe devido ao segundo bloco de reescrita.
bare.domain
O vhost bare.domain está recebendo as solicitações *.*
e as atende /domain.com/www
Aqui, o RewriteRule
será o proxy para o localhost quando domain.com
ou domain.com/www
não existirem.
^ $%. * !!!
Eu tive alguns problemas em enrolar minha cabeça em todos os sinais $
e %
no RewriteCond
e RewriteRule
, então 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.
- Os
%n
no VirtualDocumentRoot
são da interpolação do nome do documento .
- O
%n
no segundo RewriteCond
refere-se às seleções (.*)
do primeiro RewriteCond
, por exemplo. as partes do domínio solicitado.
- O
%n
no RewriteRule
também.
- O
$1
no RewriteRule
refere-se à seleção (.*)
no início do RewriteRule
. Que captura tudo, desde o domínio até o ?
no URL da solicitação. Qualquer querystring é automaticamente adicionada ao URL por mod_proxy
.