Configure a CentOS 6.4 Web Server on Rackspace - Part 4: Virtual Hosts
You'll probably want to host multiple domains on your server. To do that we will need to set up Apache virtual hosts. There is more than one way to do this. The configuration below assumes that there is one server administrator who manages multiple hosted domains. In other words, this setup is good for web developers who host their own clients and manage their client's sites.
First, change permissions on the admin user's directory:
$ sudo chmod 755 /home/admin
Create the First Hosted Domain
Create a home directory for your first hosted domain. We'll use www.mydomain1.com as an example. Note that further down when we edit the Apache settings in the httpd.conf file we'll be enforcing the www version as our canonical domain, so we need the directory name to match. If you plan to enforce the non-www version, then don't include the www in the directory name either.
$ mkdir -p /home/admin/sites/www.mydomain1.com/public_html
Add an index.html file to the hosted domain's public folder:
$ vim /home/admin/sites/www.mydomain1.com/public_html/index.php
And add some code to the index.php file:
<?php
echo phpinfo();
You can repeat the steps above for each domain you want to host.
Configure Apache for Virtual Hosting
Open the Apache config file httpd.conf:
$ sudo vim /etc/httpd/conf/httpd.conf
Near the bottom of the file uncomment the line that reads:
NameVirtualHost *:80
Normally each hosted domain gets an separate entry in httpd.conf. However, this makes it cumbersome to add new domains. The following setup can be used for mass virtual hosting so that we won't need to add each new hosted domain to httpd.conf. With these settings, all we'll need to do is add a new directory to /home/admin/public_html/ for each new site we host. Pretty cool.
We'll also enforce the www version as the canonical domain here in httpd.conf because it's more efficient than using .htaccess.
<VirtualHost *:80>
# Redirect non-www to www for all domains
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www..+$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Set the home directory for each domain based
# on the request. %0 will be the domain name.
VirtualDocumentRoot /home/admin/sites/%0/public_html
# Fix the broken $_SERVER_[DOCUMENT_ROOT] with this hack
php_admin_value auto_prepend_file /home/admin/docroot.php
</VirtualHost>
Apache can run into memory problems if each virtual host has it's own log file. So what we'll do is combine the logs for all the domains into a single, common log file. The log file can be split programmatically on a per-virtualhost basis for reporting, etc.
In httpd.conf, search for LogFormat. Add the following 2 lines right after the existing entries for LogFormat:
LogFormat "%V %h %l %u %t "%r" %>s %b" vhost
CustomLog /home/admin/logs/vhost.log vhost
Save and close httpd.conf.
Logging
Create a directory to store the log files:
$ mkdir /home/admin/logs
$ touch /home/admin/logs/vhost.log
$ chmod 664 /home/admin/logs/vhost.log
Log files can get big quickly, so we need to make sure the logrotate program knows about our vhost.log file. We just need to add our new log file to the existing Apache logrotate configuration:
$ sudo vim /etc/logrotate.d/httpd
The first line of the file should look like this:
/var/log/httpd/*log {
We're going to add the path to our vhost.log file right after the existing path. Make sure there's a space separating the file paths. So your first line should now be:
/var/log/httpd/*log /home/admin/logs/vhost.log {
The next few lines of the file are a stack of commands (see this Slicehost article for more details). We'll leave them as is, but let's add one additional command right at the top of the stack:
size 10M
Now our logs will rotate every week, or when they reach 10 megabytes, whichever comes first. I would also recommend installing Logwatch to get daily email reports about the state of your server.
Finishing Up
In the last line of the VirtualHost block in httpd.conf you may have noticed a reference to a file called docroot.php. That file is a hack that is used to fix the broken DOCUMENT_ROOT that results from this mass virtual hosting configuration. With the hack in place we will be able to use $_SERVER[DOCUMENT_ROOT] in PHP and get the correct result. Create the file with $ vim /home/admin/docroot.php, then add the following contents:
<?php
$docroot = str_replace($_SERVER['SCRIPT_NAME'], '',
$_SERVER['SCRIPT_FILENAME']);
$_SERVER['DOCUMENT_ROOT'] = $docroot;
apache_setenv("DOCUMENT_ROOT", $docroot);
Finally, let's restart Apache so the new configuration takes effect:
$ sudo service httpd restart
Now we should be able to go to www.mydomain1.com and see our test page (assuming we've set up the DNS for www.mydomain1.com of course).
Additional Resource: Slicehost article on another virtual host configuration