At work, we had set up some wildcard virtual hosts in Apache config, and that got us by for quite some time. But the time came when we needed finer-grained control of where to send incoming requests for different domains. I needed to store my virtual hosts in a Mysql database, mapping domains to project directories.
I’ll spare you the problems I ran into and overcame, and just list the steps to get this done. These instructions are based on a 64-bit, RHEL 5 server running the pre-packaged Apache server. So if you follow these instructions on a different setup, of course, filenames, directories, versions, etc. may differ.
dbd-modules from Google Code. This is a great piece of code in the form of an Apache module that uses
mod_dbd and a DBD Mysql (or other database) driver to fetch the
DocumentRoot for a given domain from a database.
% wget http://dbd-modules.googlecode.com/files/dbd-modules-1.0.5.zip
Unzip the archive in a directory. As indicated on the website, build and install the module.
% apxs -c mod_vhost_dbd.c % apxs -i mod_vhost_dbd.la
/usr/lib64/httpd/modules. Enable both this module and
mod_dbd by adding two lines to
httpd.conf, or equivalently creating a new include file in
/etc/httpd/conf.d containing these lines.
LoadModule dbd_module modules/mod_dbd.so LoadModule vhost_dbd_module modules/mod_vhost_dbd.so
In true unit fashion, now might be a good time to restart Apache, just so you can be sure everything is working up to this point.
% service httpd restart
Install Mysql DBD Driver to APR
Unfortunately, on my system, the Mysql DBD driver was nowhere to be found. I had to rebuild Apache Portable Runtime (APR) utils with the Mysql driver enabled.
% wget http://archive.apache.org/dist/apr-1.2.8.tar.bz2 % wget http://archive.apache.org/dist/apr-util-1.2.8.tar.bz2
Unpack and untar these archives in the same parent directory.
Build and install APR. Now, I do not think this is absolutely necessary, but it seems like a good idea to keep the versions in sync.
% ./configure --prefix=/usr % make % make install
Build and install
apr-util. Due to licensing issues,
apr-util does not actually contain the Mysql DBD driver until
apr-util-1.2.12. Prior to that version, it must be downloaded separately, and the configure script rebuilt.
% wget http://apache.webthing.com/svn/apache/apr/apr_dbd_mysql.c % ./buildconf --with-apr=../apr-1.2.7
Now for the three commands every Linux admin loves.
% ./configure --prefix=/usr --with-apr=/usr --libdir=/usr/lib64 --with-expat=builtin --with-ldap-include=/usr/include --with-ldap-lib=/usr/lib64 --with-ldap=ldap --with-mysql % make % make install
The first time I tried this, Apache could not find any LDAP-related modules. Adding those configure switches seemed to do the trick. Restart Apache.
% service httpd restart
Apache should now be able to query a Mysql database to get the
DocumentRoot for a domain. My
VirtualHost block looked something like this.
<VirtualHost *:80> ServerName *.example.com DocumentRoot "/path/to/default/document/root" DBDriver mysql DBDParams host=localhost,user=root,pass=secret,dbname=vhosts DBDocRoot "SELECT path FROM vhosts WHERE host = %s" HOSTNAME </VirtualHost>
For more details and instructions on
mod_vhost_dbd configuration directives, read the project wiki.
To test things on our RHEL 5 production servers, I fire up CentOS 5 in VMWare. While we build PHP 5.2 manually in production, I try to avoid doing so just for testing. Unfortunately, CentOS 5 is packaged with PHP 5.1 by default which becomes a big difference between my testing and production environments. Fortunately, there is a CentOS yum repository out there with PHP 5.2. I thought I’d document this here for anyone else with the same problem.
The solution I found starts with this thread about upgrading PHP on the CentOS forums. To summarize, run these commands:
% cd /etc/yum.repos.d % wget http://dev.cnetos.org/centos/5/CentOS-Testing.repo
Then, edit the .repo file and set the
"enabled" value to
% yum list available php Available Packages php.i386 5.2.6-2.el5s2 c5-testing