Mass Virtual Hosting with mod_rewrite RewriteMap and PHP
Here is a simple possibility to control a lot of virtual hosts using a simple PHP script to map them to the right path.
First of all you need to make sure that mod_rewrite is loaded:
a2enmod rewrite
Further we need these packages:
php5-cli php5-mysql mysql-server
What we're doing now is a simple Url-Rewriting to a PHP script, so we're changing /etc/apache2/apache2.conf:
RewriteEngine on
RewriteMap lowercase int:tolower
RewriteMap vhost prg:/etc/apache2/vhost.php
RewriteLock /var/run/apache2/vhost.lock
RewriteCond %{REQUEST_URI} !^/icons/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/$1
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
As backend, the simpliest solution is a mysql database (replacing username and password):
mysql –user=XXXXXXXXXX –password=XXXXXXXXXX;
CREATE DATABASE srvadm;
USE srvadm;
CREATE TABLE `vhosts` (
`vhost_id` int(5) NOT NULL auto_increment,
`domain` varchar(100) NOT NULL,
`document_root` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`lastmodified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`vhost_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Finally you have to create your PHP script /etc/apache2/vhosts.php (replacing username and password):
#!/usr/bin/php
<?php
//Configuration
define('DB_HOST','localhost');
define('DB_USER', 'XXXXXXXXXX');
define('DB_PASSWORD', 'XXXXXXXXXX');
define('DB_NAME', 'srvadm');
$db = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die('COULD NOT CONNECT TO DB');
mysql_select_db(DB_NAME) or die('DATABASE NOT FOUND OR NOT ACCESSIBLE');
if ($stdin=fopen("php://stdin","r")) {
while (!feof($stdin)) {
//Domain name via STDIN auslesen
$domain = fgets($stdin,4096);
//document_root anhand der Domain aus der Datenbank auslesen
$result = mysql_query("SELECT document_root FROM vhosts WHERE domain='".trim($domain)."' ");
$arr = mysql_fetch_assoc($result);
$output = $arr[‘document_root’];
if ($stdout = fopen("php://stdout", "w")) {
fwrite($stdout,$output."n");
fclose($stdout);
}
}
fclose($stdin);
}
mysql_close($db);
?>
Then just restart apache to make it work:
/etc/init.d/apache2 restart