7
votes

This is probably an easy question, but I want to understand better how Apache works with virtual hosts. I am setting up virtual hosts because I work on multiple websites at once and I don't want to use subdirectories. I was pretty much using the default Apache httpd.conf file with the DocumentRoot pointing to something like "/www". I uncommented the virtual hosts include and added the following:

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName site1.dev
    DocumentRoot /www/site1
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.dev
    DocumentRoot /www/site2
</VirtualHost>

Now when I go to http://localhost I get the default page for site1.

I'm sure there is a reason why this makes sense, but I don't quite understand it. I would've thought that only requests that were explicitly to http://site1.test would get routed through that directive and it wouldn't just become the default. Can someone explain why it becomes the default.

5
+1 because I keep forgetting thisDavid

5 Answers

11
votes

http://httpd.apache.org/docs/1.3/vhosts/name-based.html

(Should be true for 2.x also)

"If no matching virtual host is found, then the first listed virtual host that matches the IP address will be used.

As a consequence, the first listed virtual host is the default virtual host. The DocumentRoot from the main server will never be used when an IP address matches the NameVirtualHost directive. If you would like to have a special configuration for requests that do not match any particular virtual host, simply put that configuration in a container and list it first in the configuration file."

4
votes

answer 1 is correct and i'd add with namevirtualhosts as the first entry essentially matches any not-named elsewhere virtualhost

it should ONLY be used to catch unintentional mal-formed and broken traffic

ie a machene with one ip called john.domain.com running www.domain.com and www.domain2.com as valid webservers on ip www.xxx.yyy.zzz might have an optimal config like thus

    <VirtualHost *:80>
     DocumentRoot /var/webserver/static-sites/unknown/
    # a directory readable by apache with only a robots.txt denying everything
     ServerName bogus
     ErrorDocument 404 "/errordocuments/unknown-name.html"
    #custom 404 describing how/what they might have done wrong try pointing a browser {with a hosts file at http://bogus/ on 193.120.238.109 to see mine#
     ErrorLog /var/log/httpd/unknown-error.log
     CustomLog /var/log/httpd/unknown-access.log combined
    </VirtualHost>

    <VirtualHost *:80>
     DocumentRoot /var/webserver/static-sites/unknown/
    # a possibly different directory readable by apache with only a robots.txt denying everything
     ServerName www.xxx.yyy.zzz
     ServerAlias john.domain.com
     ErrorDocument 404 "/errordocuments/ip-name.html"
     ErrorDocument 403 "/errordocuments/ip-name.html"
    #custom 404 telling them as a likely hacker/bot you wish to have nothing to do with them see mine at http://193.120.238.109/
     ErrorLog /var/log/httpd/ip-error.log
     CustomLog /var/log/httpd/ip-access.log combined
    </VirtualHost>

    <VirtualHost *:80>
     ServerName domain.com
     RedirectPermanent / http://www.domain.com/
     ErrorLog logs/www.domain.com-error.log
     CustomLog logs/www.domain.com-access.log combined
    </VirtualHost>

    <VirtualHost *:80>
     DocumentRoot /var/webserver/ftpusers/domain
     ServerName www.domain.com
     ServerPath /domain
     ErrorLog logs/www.domain.com-error.log
     CustomLog logs/www.domain.com-access.log combined
    </VirtualHost>

    <VirtualHost *:80>
     ServerName domain2.com
     RedirectPermanent / http://www.domain2.com/
     ErrorLog logs/www.domain2.com-error.log
     CustomLog logs/www.domain2.com-access.log combined
    </VirtualHost>

    <VirtualHost *:80>
     DocumentRoot /var/webserver/ftpusers/domain2
     ServerName www.domain2.com
     ServerPath /domain2
     ErrorLog logs/www.domain2.com-error.log
     CustomLog logs/www.domain2.com-access.log combined
    </VirtualHost>
3
votes

Confirming that for Apache 2.x, the first virtual host (with the same port number) will be used if a matching virtual host is not found.

http://httpd.apache.org/docs/2.2/vhosts/details.html

"If no matching vhost could be found the request is served from the first vhost with a matching port number that is on the list for the IP to which the client connected"

You can always add this code below, put it right below NameVirtualHost *:80 so that your default document root is served by default if no other virtual hosts found.

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot /my/default/document/root
</VirtualHost>
1
votes

Simply put this code at top in httpd-vhosts.conf

<VirtualHost localhost:80>
    ServerName localhost
    DocumentRoot d:/xampp/htdocs
    <Directory  "d:/xampp/htdocs/">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require local
    </Directory>
</VirtualHost>
0
votes

One way to do this is:

  1. In your VirtualHosts configuration, enter the specific local site name you want to enable instead of using a wildcard: <VirtualHost site1.dev:80> instead of <VirtualHost *:80>

  2. Switch off NameVirtualHost *:80 which can be done by commenting it out in your vhosts.conf file

  3. In your /etc/hosts file mention both aliases for the loopback IP: 127.0.0.1 localhost site1.dev

That's it. You should see that localhost goes to the default DocumentRoot as usual and the site1.dev goes to the site you've setup as virtual host.