Apache Virtual Hosts on CentOS - part 1

Now that apache is running and configured on your CentOS 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.

Rather than uncomment the line for NameVirtualHost in the main config file, let's create a new config file to hold the setting. We can call it "namevirtualhost.conf", a nice descriptive name. Edit the file:

sudo nano /etc/httpd/conf/custom/namevirtualhost.conf

Let's just set NameVirtualHost to apply name-based virtual host logic and settings for HTTP requests made on any available interface (*) at port 80:

NameVirtualHost *:80

Custom Virtual Hosts

We've set up the basics and now we're ready to add our own virtual hosts.

First we should set up a new directory to hold our virtual host config files. Putting each virtual host in its own file will make it easier to edit, enable, or disable them in the future:

sudo mkdir /etc/httpd/conf/vhosts

We'll also add a line to the end of the main apache config file (/etc/httpd/conf/httpd.conf) to read files from that directory:

Include conf/vhosts/*.conf

Make sure this Include is placed after the Include for the "custom" directory. It's a bit safer to have the virtual host configurations load after any other configuration changes, like enabling NameVirtualHost.

Now let's go ahead and create the vhost file for domain1:

sudo nano /etc/httpd/conf/vhosts/domain1.com.conf

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>

Reload apache

To have apache use the new virtual domain we'll need it to reload its settings:

sudo /usr/sbin/apachectl graceful

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/httpd/conf/vhosts/domain2.com.conf
...
# Enter the details for domain2.com as per the example shown above

To enable the site reload Apache:

sudo /usr/sbin/apachectl 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 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

It's important to note that apache is still set up with its default site configuration - listening to port 80, using a DocumentRoot of /var/www/html, and several other details you can dig out of the main apache config file. You might want to change some of those default settings to match your primary site.

Another option is to comment out the following line in the httpd.conf file, changing this:

DocumentRoot "/var/www/html"

to this:

#DocumentRoot "/var/www/html"

Now apache will still treat the first DocumentRoot it finds as the default, and that will be in the vhost config file that comes first alphabetically in your vhosts directory. If your primary domain doesn't come first alphabetically, put a "0" at the start of the file to make sure its config will.

You can then also comment out any other configuration options in the httpd.conf file that you would prefer to have set by your default virtual host instead.

Summary

We've gone into some detail here but, overall, setting up a virtual host is relatively straightforward. 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 host article will look in more detail at some of the settings that are available and what they mean.

  • -- Jered

Article Comments:

Brian Zuvich commented Wed Jun 02 09:20:12 UTC 2010:

I just wanted to point out that a2ensite is mentioned in your document. I believe A2ensite is only available on Debian systems.

Jered commented Wed Jun 02 14:25:24 UTC 2010:

I really need to get better at the editing process if I'm going to try and adapt the articles for each distro from one template. Thanks for catching that Brian, it's fixed now.

KnightSoft commented Thu Jun 03 03:57:20 UTC 2010:

Hey Jered, A truly good article, made the process very easy. Everything appears ok on my own setup, however, I am getting a 403 forbidden on my virtual hosts (not on the default virtual host I also have). I have tried for a few hours to no avail to set the correct permissions. Can you clarify what I need to do to the public_html folder and the domain1/2.com folders, permissions wise?

KnightSoft commented Thu Jun 03 04:46:57 UTC 2010:

Thankyou Jered but I have answered my own question! Finally worked it out, I had to set the permissions on all the directories too, all the way up to root. Re this document, for reference: http://wiki.apache.org/httpd/13PermissionDenied

Jered commented Thu Jun 03 05:56:13 UTC 2010:

Good to hear, KnightSoft. You're not the first person I've seen run into that problem with permissions, definitely. I'll see if I can't come up with a way to work that into the article in a revision.

Brian Zuvich commented Sat Jun 26 21:27:03 UTC 2010:

Not a problem Jered. As much as these articles have helped me, pointing out a tiny little error is the LEAST I can do.

Antonio commented Thu Jul 15 17:20:56 UTC 2010:

Could someone tel me how to fix the 403 forbidden on my virtual hosts? I am not being able to do it even looking into @Jered proposed. Thanks

Jered commented Fri Jul 16 07:41:58 UTC 2010:

Antonio, hop into support chat (if you haven't already) and someone there can help you figure out what's causing the 403 error. It's most likely a permissions issue - I'll add some details about permissions to this article soon, that was definitely an oversight on my part.

jeelan commented Thu Dec 09 18:01:12 UTC 2010:

In apache .html web-pages how to include graphics and videos, is there any script to attach it?

Jered commented Fri Dec 10 19:34:51 UTC 2010:

Jeelan, including graphics and videos are done in the HTML code within a .html file. You should be able to find information on embedding images or videos with some Google searches. For basic HTML, including embedding images, you might look at this HTML tutorial.

David A commented Sun Mar 20 00:56:50 UTC 2011:

Hi Jered

Great how to guides. Certainly one of the most clear and concise I have found that a newbie can follow.

I was wondering if you could help me. I have followed your instructions and I am having issues. Let me give you a quick rundown on how I have set things up.

I am running Centos 5 and have LAMP set up using the yum install command.

With the default apache install i can access pages found at /var/www/html through my browser. I create an index.php file that contains nothing more: <?php phpinfo(); ?>

So when I got to my web browser and go to: http://localhost/ I get the php info page. I installed phpMyAdmin and can access this through http://localhost/phpMyAdmin

Now I want to install drupal so I can teach myself how to use drupal. I initially edited httpd.conf and included the following virtual host entry (with the help of webmin) <virtualhost> DocumentRoot "/home/admin/public_html/drupal" ServerName drupal.local <directory> allow from all Options +Indexes </directory> </virtualhost> No logging, i know, I just want to get it working first, then set up logging I also added the following entry to /etc/hosts 127.0.0.1 drupal.local

However when i would go http://drupal.local I would get the following error: Forbidden

You don't have permission to access / on this server. Apache/2.2.3 (CentOS) Server at drupal.local Port 80

To top things off, I found that if i then revisted http://localhost or http://localhost/phpMyAdmin I would get the same error.

So i rolled back httpd.conf and then made the changes listed in your guide here. Namely:

  • I created /etc/httpd/conf/custom/namevirtualhost.conf and added the line: NameVirtualHost *:80
  • I ran sudo mkdir /etc/httpd/conf/vhosts
  • I added the following lines to httpd.conf (underneath the default entry Include conf.d/*.conf): Include conf/custom/*.conf Include conf/vhosts/*.conf
  • I then create /etc/httpd/conf/vhosts/drupal.conf that contains <virtualhost> DocumentRoot "/home/admin/public_html/drupal" ServerName drupal.local <directory> allow from all Options +Indexes </directory> </virtualhost>
  • I then restarted apache and still the same error

I know its not a permission issue as I followed drupal's recommendation of changing the ownership and group to apache and given all files the permission 755. I know this works because if I copy this drupal folder to /var/www/html/drupal I can access it via http://localhost/drupal with the default apache configuration.

I am really stuck and just cant seem to move forward. Any help you could offer would be very much appreciated.

Thanks in advance

David A

The Coupon Guy commented Tue Dec 27 15:42:21 UTC 2011:

David A, What you need to do is just chmod 755 the user account. For example, your user account name is "demo". You have to chmod 755 /home/demo

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)