I wrote this script a while back, and I’ve been using it on gentoo, ubuntu and centos distros with a few changes between each distro, this can be extended to add new functionality, and it may contain bugs, but so far it has worked for me pretty well, I can add/remove virtual hosts very quickly.

To use this script you only need the packages File::Path and Getopt::Long; both of them are already on newer distros, just put the script somewhere in your bin path, I have it in /usr/local/bin and call it with sudo.

ivan@orion:/var/www/vhosts$ sudo vhost-updater.pl --add --domain test.orion

This is the output:

Creating docroot dir: /var/www/vhosts/test.orion/public_html 
Creating log dir: /var/www/vhosts/test.orion/logs 
Site File: /etc/apache2/sites-available/test.orion 
Creating Vhost... 
Adding host test.orion 
Run '/etc/init.d/apache2 reload' to activate new configuration!
Restarting apache 
 * Restarting web server apache2
 ... waiting    ...done.

Once it has finished, point your browser to http://test.orion, and you’re done.

Enjoy!

#!/usr/bin/perl -w

#############################################################
# The purpose of this script is to add/remove               # 
# virtual hosts easily, this script runs                    #
# on Ubuntu/Debian withouth modifications.                  #
#                                                           #   
#                                                           #   
# Author Ivan Villareal ivaano@gmail.com                    #
#                                                           #   
#############################################################
use strict;
use File::Path qw(mkpath rmtree);
use Getopt::Long;


our $ipAddress        = '127.0.0.1';
our $apacheConfigDir  = '/etc/apache2';
our $sitesAvailable   = 'sites-available';

our $docRootPrefix    = '/var/www/vhosts';
our $docRoot          = 'public_html';
our $logsDir          = 'logs';



my $del = '';
my $add = '';
my $domain = '';

if (getpwuid( $< ) ne 'root') {
    print "Script needs root privileges \n";
    exit();
}

unless (GetOptions (
        'del' => \$del, 
        'add' => \$add, 
        'domain=s' => \$domain) or usage()) {
    usage();
}

#print $paramResults;
if ($add || $del) {
    if ($domain) {
        if ($add) {
            createVhost($domain);
        } elsif ($del) {
            deleteVhost($domain);
        }
    } else {
        usage();
    }
} else {
    usage();
}


sub usage {
    print < <USAGE
This program will add or remove apache virtual hosts.

usage: vhost-updater.pl [--add | --del] --domain newhost.tld 
USAGE
}

sub returnVhostPaths
{
    my $vhost = shift;
    my @dir = split(/\//, $docRootPrefix);
    my %res;
    
    push(@dir, $vhost);

    my $hostDir = join('/', @dir);
    $res{'docRoot'} = $hostDir . '/' . $docRoot;
    $res{'logsDir'} = $hostDir . '/' . $logsDir;
    $res{'hostDir'} = $hostDir;
    #todo dir validation
    @dir = split(/\//, $apacheConfigDir);
    push(@dir, $sitesAvailable);
    push(@dir, $vhost);
    $res{'apacheConfig'} = join('/', @dir);
    
    return %res;   
}

sub createVhost {
    my $vhost = shift;
    #first create the docRoot
    my %vhostInfo = returnVhostPaths($vhost);
    
    informOut("Creating docroot dir: $vhostInfo{'docRoot'}");
    mkpath($vhostInfo{'docRoot'});
    my $user = getlogin();
    my $uid  = getpwnam($user);
    my $gid  = getgrnam($user);
    chown $uid, $gid, $vhostInfo{'hostDir'};
    chown $uid, $gid, $vhostInfo{'docRoot'};
    informOut("Creating log dir: $vhostInfo{'logsDir'}");
    mkpath($vhostInfo{'logsDir'});
    

    informOut("Site File: $vhostInfo{'apacheConfig'}");
    
    my $vhostContent = << "EOF";
<VirtualHost *:80>
    ServerName $vhost
    DocumentRoot $vhostInfo{'docRoot'}
    <directory $vhostInfo{'docRoot'}>
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </directory>
        ErrorLog $vhostInfo{'logsDir'}/error_log
        CustomLog $vhostInfo{'logsDir'}/access_log "%h %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-agent}i\\""
        LogLevel debug


EOF
    informOut("Creating Vhost...");
    open FILE, ">", $vhostInfo{'apacheConfig'} or die $!;
    print FILE $vhostContent;
    close FILE;
    
    informOut("Adding host $vhost");
    open FILE, ">>", '/etc/hosts' or die $!;
    print FILE $ipAddress ."\t". $vhost ."\n";
    close FILE;
      
    my $output = `/usr/sbin/a2ensite $vhost`;
    print $output;
   
    restartApache();
    #print $vhostConten t;
}

sub restartApache
{
    informOut("Restarting apache");
    my $output = `/etc/init.d/apache2 restart`;
    print $output; 
}

sub deleteVhost
{
    my $vhost = shift;
     my %vhostInfo = returnVhostPaths($vhost);
     
    informOut("Removing $vhost from hosts file");
    open IN, '< ', '/etc/hosts' or die $!;
    my @hostsFile = <IN>;
    close IN;
    
    my @contents = grep(!/^127.0.0.1\t$vhost/, @hostsFile);
    
    open FILE, ">", '/etc/hosts' or die $!;
    print FILE @contents;
    close FILE;
    
    my $output = `/usr/sbin/a2dissite $vhost`;
    print $output;
    
    informOut("Removing  $vhostInfo{'apacheConfig'} file");
    unlink($vhostInfo{'apacheConfig'});
    
    restartApache();
        
    print " manually remove $vhostInfo{'docRoot'}... \n";
    
}

sub informOut {
    my $message = shift;
    print "$message \n";
}