Wildcard domains with virtualhost with Apache on M

2019-02-25 17:40发布

问题:

I'm currently running several domains for local development

http://wordpress.dev
http://phpmyadmin.dev
http://projectx.dev
http://projecty.dev
...

Most of these projects are located in the users "Sites" directory but some are located somewhere else:

/Users/[username]/Sites/wordpress
/Users/[username]/Sites/phpmyadmin
/Users/[username]/Sites/projectx
/Users/[username]/OtherDirectory/projecty

I'm currently setup all by adding dedicate entries to the /etc/hosts and /etc/apache2/extra/httpd-vhosts.conf

/etc/hosts:

127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost 
fe80::1%lo0     localhost
# Virtuelle Hosts
127.0.0.1       wordpress.dev
127.0.0.1       phpmyadmin.dev
127.0.0.1       projectx.dev
....

/etc/apache2/extra/httpd-vhosts.conf:

<VirtualHost *:80>
    ServerName [PROJECT].dev
    ServerAlias [PROJECT].dev
    DocumentRoot /Users/[username]/Sites/[PROJECT]/
    <Directory /Users/[username]/Sites/[PROJECT]/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
</VirtualHost>
<VirtualHost *:80>
 ...

Is there a way to use some kind of wildcard settings to map the domain to a certain directory like

http://foo.dev =>  /Users/[username]/Sites/foo
http://bar.dev =>  /Users/[username]/Sites/bar
...

while keep projecty working (with some extra settings of course) so I only have to create a folder in Sites which is instantly accessible via http://[foldername].dev

The [username] can be hardcoded

回答1:

Use mod_vhost_alias and a VirtualDocumentRoot

As long as you have no VirtualHost catching foo.dev as a ServerName or ServerAlias you should be able to do the following:

<VirtualHost *:80>
  ServerName default.dev

  VirtualDocumentRoot /Users/youruser/%-2
  ...
  ...
</VirtualHost>

You'll need the username to be hardcoded, though you say that's not a problem.

%-2 in the VirtualDocumentRoot represents the penultimate dot-separated part of foo.com, i.e. foo. You could then have directories as you wish that map to the sites:

http://foo.dev =>  /Users/youruser/Sites/foo
http://bar.dev =>  /Users/youruser/Sites/bar
http://subdom.baz.dev =>  /Users/youruser/Sites/baz

You'll need to make sure that any additional domains you want to map in this fashion have an appropriate entry in your hosts file, or DNS if you're using that.



回答2:

In order to accomplish what you need, you can configure a dynamically configured mass virtual host.

To have it you should add something like the following to your httpd.conf file:

# get the server name from the Host: header
UseCanonicalName Off

# this log format can be split per-virtual-host based on the first field
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon

# include the server name in the filenames used to satisfy requests
VirtualDocumentRoot /www/hosts/%0/docs
VirtualScriptAlias /www/hosts/%0/cgi-bin 

That would do the same as the following:

NameVirtualHost 111.22.33.44
<VirtualHost 111.22.33.44>
    ServerName www.customer-1.com
    DocumentRoot /www/hosts/www.customer-1.com/docs
    ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
</VirtualHost>
<VirtualHost 111.22.33.44>
    ServerName www.customer-2.com
    DocumentRoot /www/hosts/www.customer-2.com/docs
    ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
</VirtualHost>
# blah blah blah
<VirtualHost 111.22.33.44>
    ServerName www.customer-N.com
    DocumentRoot /www/hosts/www.customer-N.com/docs
    ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
</VirtualHost> 

For more details on this, check here