Gentoo - Apache Virtual Hosts #1

Now that we have Apache installed and running, we can configure it to serve multiple domains using Virtual Hosts.

Do note the layout used in these articles is explained here — feel free to use the directories of your choice.


Create the layout

In this example we'll be using two domains: domain1.com and domain2.com.

In your home directory create a 'public_html' folder:

cd ~
mkdir ~/public_html

Now for each domain we want to host, create a folder with a standard set of sub-folders:

mkdir -p ~/public_html/domain1.com/{public,private,log,cgi-bin,backup}

and

mkdir -p ~/public_html/domain2.com/{public,private,log,cgi-bin,backup}

That will create the folders public, private, log, cgi-bin and backup for each of our domains (domain1.com and domain2.com).

index.html

The content of the public folder is up to you; for this example I am going to use a very simple html file so we can check that the virtual hosts work.

So for each domain create an index.html file:

nano ~/public_html/domain1.com/public/index.html

Then add the following to the index.html file:

<html>
  <head>
    <title>domain1.com</title>
  </head>
  <body>
    <h1>domain1.com</h1>
  </body>
</html>

Repeat the process so you have a similar file for domain2.com — simply replace all instances of 'domain1.com' with 'domain2.com'.

OK, now we have a basic structure for our two domains and can look at defining two virtual hosts.

NameVirtualHost

With virtual hosts, one thing that often confuses people is the NameVirtualHost setting.

For each interface and port on which Apache is set to listen, we need a NameVirtualHost directive. Something to keep in mind is you can only define it once per host-port combination.

In the Apache layout for Gentoo there is a default NameVirtualHost directive in the '/etc/apache2/vhosts.d/00_default_vhost.conf' file. Let's a take a closer look at this file now.

/etc/apache2/vhosts.d/00_default_vhost.conf

This file actually enables 'name based virtual hosts' for all files loaded after it, so it's important that it's loaded first; hence the file-name starting with '00_'.

There is another directive specifically for SSL-enabled sites in the file '/etc/apache2/vhosts.d/00_default_ssl_vhost.conf'. I'll leave looking at this file as an exercise for the reader.

Lets take a tour of the non-ssl file:

nano /etc/apache2/vhosts.d/00_default_vhost.conf

The first directive we come across is

Listen 80

This tells Apache to listen for connections on port 80, the default port for web servers. You could make it listen on other ports by adding other directives like 'Listen 8080', then connect using that port with something like: 'http://1.2.3.4:8080' (where 1.2.3.4 is the IP address of your Slice).

The next directive we find is:

NameVirtualHost *:80

This directive tells Apache that we'll be using 'name based virtual hosts' on all network interfaces on port 80. Without it, Apache would always show the same site, no matter what address was typed into the browser's location bar.

The next part of this file contains the default virtual host block; we won't be changing this, instead we'll make our own virtual host in a new file.

One thing to note is how both the ssl and the non-ssl files import a common core with the line:

Include /etc/apache2/vhosts.d/default_vhost.include

We'll employ the same idea in our own virtual host declarations.

Custom Virtual Hosts

Now we're ready to add our own virtual hosts so we can start to serve our domains.

Let's go ahead and create the non-ssl vhost file for domain1:

sudo nano /etc/apache2/vhosts.d/domain1.com.conf

The contents look like this:

<VirtualHost *:80>
    ServerName domain1.com
    Include /etc/apache2/vhosts.d/domain1.com.include
</VirtualHost>

Now lets make the meat of the vhost; should we come to make an SSL version of this vhost later, it will be easy to import this file:

sudo nano /etc/apache2/vhosts.d/domain1.com.include

The contents look like this:

# Admin email, Server Name (domain name) and any aliases
ServerAdmin webmaster@domain1.com
ServerName  domain1.com
ServerAlias www.domain1.com

# Index file and Document Root (where the public files are located)
DirectoryIndex index.html
DocumentRoot /home/demo/public_html/domain1.com/public

<Directory "/home/demo/public_html/domain1.com/public">
    # Allow Apache to followlinks
    Options FollowSymLinks

    # Turn on the ability to use .htaccess files
    AllowOverride All

    # Controls who can get stuff from this directory
    Order allow,deny
    Allow from all
</Directory>

# Custom log file locations
LogLevel warn
ErrorLog  /home/demo/public_html/domain1.com/log/error.log
CustomLog /home/demo/public_html/domain1.com/log/access.log combined

Remember to change 'demo' to your own username. Once this file is created, we just need to let Apache know about it:

sudo /etc/init.d/apache2 reload

Navigate

To test the domain without creating a DNS zone and record(s) on some Internet namserver(s), I've modified the '/etc/hosts' file on my local (home/office) computer to include some entries mapping 'domain1.com', etc. to the demo Slice's public IP:

127.0.0.1    localhost
...

# Override and pre-view DNS for the demo Slice
1.2.3.4   domain1.com www.domain1.com domain2.com www.domain2.com
...

You can add similar entries in your own 'hosts' file, though it's location will vary depending on what OS is loaded on your local computer (try a Google search). Of course you should replace 1.2.3.4 with your Slice's public IP.

NOTE: Entries in the 'hosts' file will need to be removed prior to testing and using live DNS zones and records created on Internet nameservers. Failure to remove them will likely lead to confusion on your part and inaccurate tests of new or modified public DNS records.

With such changes made for testing purposes, you can navigate to your site in a web browser on your local computer:

Domain1 Home Page

Tada! The contents of public/index.html on your slice are being displayed in your local browser.

ServerAlias

Note that in the vhost file, we set a ServerAlias. Provided you have the DNS set up correctly, you can also load that address in your local browser. For quick testing purposes you can place another entry in your 'hosts' file. I've already done so in the example code above:

Domain1 Home Page (hostname alias)

We'll discuss forcing one address vs. another in a later article about "rewrite rules".

Repeat as necessary

To create and enable domain2.com simply go through the process again:

sudo nano /etc/apache2/vhosts.d/domain2.com.conf
...
# Enter the details for domain2.com as per the example shown above

To enable the site reload Apache:

sudo /usr/sbin/apache2ctl graceful

Finally add a hosts entry to your local machine and navigate to your second domain:

http://domain2.com
or
http://www.domain2.com

All being well, you will see the "domain2.com" index file.

Log Files

As defined in the vhost files, each domain has its own log files. Let's take a quick look:

ls /home/demo/public_html/domain1.com/log/

The output is exactly as expected:

access.log  error.log

This makes for much easier analysis as each set of logs is self-contained.

Default

If someone enters the IP address of you Slice into their local browser, they are served the contents indicated by the default vhost file (provided you haven't set up a separate vhost for the IP address).

Why?

Apache searches the enabled vhosts in alpha-numerical order and if it can't find one for the requested IP address or domain name, it serves the first one (alpha-numerically). In the case of the gentoo setup this is always '00_default_vhost.conf' for non-ssl vhosts, or '00_default_ssl_vhost.conf' for ssl vhosts.

To change what content is displayed when no vhost matches a requested domain pointing to your slice's IP, you can alter the file '/etc/apach2/vhosts.d/default_vhost.include'.

This is something to keep in mind when planning your websites. Do you want a particular domain to be the default? Do you want the plain IP address to answer HTTP requests with completely different content?

Summary

We've gone into some detail here. Overall, though, setting up a virtual host is relatively easy. Of course, there are many settings and configurations to take into account but you should have your site up and running in no time.

The next Virtual Hosts article will look in more detail at common settings and their meanings.

matiu

Article Comments:

John Poole commented Sat Oct 24 10:47:21 UTC 2009:

This concise tutorial was just what I needed; thank you.

So early visitors to your site don't have your temporary page cached so when they return later, they don't see your revised page, add:

ExpiresDefault "access plus 2 days"

(Ensure you have the mod_expires module activated: LoadModule expiresmodule modules/modexpires.so)

Freddy Taborda commented Tue Aug 17 17:24:43 UTC 2010:

Thanks for this information.

Gracias por esta informacion.

CarlosCSolano commented Fri Jan 07 13:48:17 UTC 2011:

One word: Wow! Excellent article

hardly commented Tue Jan 03 06:24:56 UTC 2012:

This was a very helpful and informative article.

... but You either left out the "a2ensite" command for the first vhost (and the part about the files in hosts-available/) OR you switched Distro's after finishing the first vhost. I am very confused.

I do not believe Gentoo comes with a2ensite or the hosts-allowed directory (as per the info in the first link: http://articles.slicehost.com/2009/10/5/gentoo-apache-config-layout).

Am I missing something or am I the only one who actually read the article? Great stuff aside from the befuddling departure from the topic distro.

Jered commented Thu Jan 05 15:50:35 UTC 2012:

You're quite right, hardly, there is no a2ensite on gentoo (unless you create it yourself, of course). Not sure why that wound up in there, but I'll tweak that section.

There's actually a newer version of this article, tweaked and updated a bit.

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)