Apache Virtual Hosts on Ubuntu – part 1


Now that apache is running and configured on your Ubuntu server we can add virtual hosts to let it serve more than one domain.

Virtual Hosts

Your apache server should be set up now, and you should have a handle on your basic configuration options. Apache may be answering requests, but if you want to be able to handle more than one domain with one web server, you’ll need to set up a virtual host for each. We’ll go through setting up a couple sample domains via virtual hosts.

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, naturally, up to you but for this example I am going to use a very simple html file so we can check the virtual hosts work.
So for each domain create an index.html file:
nano public_html/domain1.com/public/index.html
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 we can look at defining two virtual hosts.

Set the permissions

In order for apache to serve your web pages, the apache process will need to have read permissions for the various files that comprise your sites. We won’t go into detail here (you can refer to this series on permissions if you want the details later), but to make sure the permissions are the way we need them run the following two commands:
sudo chmod -R a+rX ~/public_html
sudo chmod a+rx ~
The first command sets everything in your public_html directory to be readable and accessible by all users on the system. The second command sets your home directory to be the same way (though not all the files in it, like we did with public_html). Note that the “X” in the first command is capitalized.
If you add more directories for additional virtual domains later, run that first command again to make sure the new directories are accessible as well.

NameVirtualHost

With virtual hosts, one thing that often confuses people is the NameVirtualHost setting.
For each interface and port apache is set to listen on we need a NameVirtualHost directive. Something to keep in mind is you can only define it once per port.
In the apache config layout there is a default NameVirtualHost directive in the “ports.conf” file. If you’ve worked through the first apache configuration article article, you may remember it.
Let’s take another look at the contents of “ports.conf”:
cat /etc/apache2/ports.conf
You should get the following output (unless you’ve previously modified the file):
NameVirtualHost *:80
Listen 80

<IfModule mod_ssl.c>
# If you add NameVirtualHost *:443 here, you will also have to change
# the VirtualHost statement in /etc/apache2/sites-available/default-ssl
# to <VirtualHost *:443>
# Server Name Indication for SSL named virtual hosts is currently not
# supported by MSIE on Windows XP.
Listen 443
</IfModule>

<IfModule mod_gnutls.c>
Listen 443
</IfModule>
The default NameVirtualHost setting satisfies our requirements at present — apache will apply name-based virtual host logic and settings for HTTP requests made on any available interface (*) at port 80.

Custom Virtual Hosts

We’ve set up the basics and now we’re ready to add our own virtual hosts.
Let’s go ahead and create the vhost file for domain1:
sudo nano /etc/apache2/sites-available/domain1.com
You’ll want to tailor this for your own domain, of course, changing the username, directory, and domain name involved. Make sure all the settings relevant to this particular virtual host are inside the “VirtualHost” config block, or those settings will be treated like they’re applying to apache’s main configuration (because of the way the Include directive we discussed back in the configuration files article works).
As a general template use the following:
# Place any notes or comments you have here
# It will make any customization easier to understand in the weeks to come

# domain: domain1.com
# public: /home/demo/public_html/domain1.com/

<VirtualHost *:80>

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

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

# 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

</VirtualHost>

a2ensite

Now we have the site available, we need to enable it:
sudo /usr/sbin/a2ensite domain1.com
The output of the command is:
Site domain1.com installed; run /etc/init.d/apache2 reload to enable.
Seems like good advice:
sudo /etc/init.d/apache2 reload

Navigate

To test the domain without creating a DNS zone and record(s) on some Internet nameserver(s), I’ve modified the “/etc/hosts” file on my local computer to include some entries mapping “domain1.com”, etc. to the demo server’s public IP:
127.0.0.1    localhost
...

# entries related to the demo slice
123.45.67.890 domain1.com
123.45.67.890 www.domain1.com
123.45.67.890 domain2.com
...
You can add similar entries in your own “hosts” file, though its location will vary depending on what OS is loaded on your local computer (try a Google search).
NOTE: Remember to remove those hosts entries when you’re done with testing. It can get confusing down the line if you forget they’re there, and find yourself directed to someplace other than what you’ve set in the public DNS records for your domain.
With those changes made for testing purposes, you can navigate to your site in a web browser on your local computer:
Domain1 Home Page
Tada! You should now see the index.html file you set up for your virtual host instead of apache’s default page.

ServerAlias

Note that in the vhost file we set a ServerAlias. Providing you have the DNS set up correctly you can also use that address to reach your site. For quick testing purposes you can place another entry in your “hosts” file (like I did in the example code given above):
Domain1 Home Page (hostname alias)
It is possible to force a browser that came into a site using a ServerAlias to switch to your main domain, but that involves the use of the “rewrite” module. For now we’ll let it slide, but if it’s important to switch someone to a main domain from an old one (that you would have set as a ServerAlias), you would need to look into using mod_rewrite to do it.

Repeat as necessary

To create and enable domain2.com simply go through the process again:
sudo nano /etc/apache2/sites-available/domain2.com
...
# Enter the details for domain2.com as per the example shown above
Then enable the site and restart Apache:
sudo a2ensite domain2.com
...
sudo /etc/init.d/apache2 reload
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 vhosts files, each domain has its own log files. Let’s take a quick look:
ls /home/demo/public_html/domain1.com/log/
The output should reflect what you set up in the virtual host’s config:
access.log  error.log
Keeping the logs for each domain separate means you won’t have as many log entries to dig through if you have a problem with just one particular domain.

Default

Remember that the default virtual host is still in place.
Now, if someone enters the IP address of your server they will see the site defined by that default vhosts file (providing, of course, you have not set up a separate vhost for the IP address).
Why are they served from that vhost file?
Apache searches the enabled vhosts in alphabetical order and if it can’t find one that applies specifically to the requested IP address or domain name, it just serves up the first vhost it saw.
If we had disabled or deleted the default vhost, then the contents of domain1.com would be displayed (being before domain2.com alphabetically).
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 IP address to have completely different content?

Related Posts

Subscribe Our Newsletter