Apache Named VirtualHosts with wildcards

I want to map www.example.com to a specific virtual host and then I want all other subdomains of example.com to go to another virtual host.

To do this I created these hosts:

<VirtualHost *:80>
  ServerName www.example.com
</VirtualHost>

<VirtualHost *:80>
  ServerName example.com
  ServerAlias *.example.com
</VirtualHost>

Now the selection of which host is served seems rather random. If I restart apache sometimes I will get one host and other times another.

What am I doing wrong?

Thanks!

Update: If I run apache2ctl -S on this configuration I get this outpu:

VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server www.example.com (/etc/apache2/sites-enabled/dev:3)
         port 80 namevhost www.example.com (/etc/apache2/sites-enabled/dev:3)
         port 80 namevhost example.com (/etc/apache2/sites-enabled/dev:22)

After much digging around I decided to disable the mono applications that I had running and low and behold it started serving files from the correct site. They did need to be entered in the order:

<VirtualHost *:80>
  ServerName example.com
</VirtualHost>

<VirtualHost *:80>
  ServerName www.example.com
</VirtualHost>

as suggested by Wizard. To get my mono apps working I used "MonoAutoApplication enabled" within each virtual host. However I am not sure that this is the best option as on the mono site it says you shouldn't use auto hosting for asp.net mvc apps (which is what I am using). So far I can't see the downside though.


Update: * is valid syntax but not necessary. You can find out more here.

This will work though.

<VirtualHost *:80>
   ServerName example.com
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
</VirtualHost>

The first directive will match everything that is not explicitly defined elsewhere.


The code should probably be:

<VirtualHost _default_:80>
   ServerName example.com
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
</VirtualHost>

See: http://httpd.apache.org/docs/2.2/vhosts/examples.html#default

This explicitly defines the "example.com" vhost as the host to use if nothing else matches.


Are you sure that the www.example.com vhost appears before the other vhost in the configuration file? Apache is supposed to go through the virtual hosts in order and pick the first one with a ServerName or ServerAlias that matches the value sent in the Host HTTP header. It seems very odd that it would randomly pick sometimes one virtual host and sometimes the other.

It might help to edit your question to include the output of

apache2ctl -S

which shows the defined virtual hosts as Apache sees them.


You need the DocumentRoot added to the configuration. It should be something like this:

# Ensure that Apache listens on port 80
Listen 80

# Listen for virtual host requests on all IP addresses
NameVirtualHost *:80

<VirtualHost *:80>
DocumentRoot /www/example1
ServerName www.example1.com

# Other directives here

</VirtualHost>

<VirtualHost *:80>
DocumentRoot /www/example2
ServerName www.example2.org

# Other directives here

</VirtualHost>

EDIT: Seems I thought I knew more about Apache than I do. Thanks for the comments.