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:

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

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

Enjoy!

  1. #!/usr/bin/perl -w
  2.  
  3. #############################################################
  4. # The purpose of this script is to add/remove #
  5. # virtual hosts easily, this script runs #
  6. # on Ubuntu/Debian withouth modifications. #
  7. # #
  8. # #
  9. # Author Ivan Villareal ivaano@gmail.com #
  10. # #
  11. #############################################################
  12. use strict;
  13. use File::Path qw(mkpath rmtree);
  14. use Getopt::Long;
  15.  
  16.  
  17. our $ipAddress = '127.0.0.1';
  18. our $apacheConfigDir = '/etc/apache2';
  19. our $sitesAvailable = 'sites-available';
  20.  
  21. our $docRootPrefix = '/var/www/vhosts';
  22. our $docRoot = 'public_html';
  23. our $logsDir = 'logs';
  24.  
  25.  
  26.  
  27. my $del = '';
  28. my $add = '';
  29. my $domain = '';
  30.  
  31. if (getpwuid( $< ) ne 'root') {
  32. print "Script needs root privileges \n";
  33. exit();
  34. }
  35.  
  36. unless (GetOptions (
  37. 'del' => \$del,
  38. 'add' => \$add,
  39. 'domain=s' => \$domain) or usage()) {
  40. usage();
  41. }
  42.  
  43. #print $paramResults;
  44. if ($add || $del) {
  45. if ($domain) {
  46. if ($add) {
  47. createVhost($domain);
  48. } elsif ($del) {
  49. deleteVhost($domain);
  50. }
  51. } else {
  52. usage();
  53. }
  54. } else {
  55. usage();
  56. }
  57.  
  58.  
  59. sub usage {
  60. print < <USAGE
  61. This program will add or remove apache virtual hosts.
  62.  
  63. usage: vhost-updater.pl [--add | --del] --domain newhost.tld
  64. USAGE
  65. }
  66.  
  67. sub returnVhostPaths
  68. {
  69. my $vhost = shift;
  70. my @dir = split(/\//, $docRootPrefix);
  71. my %res;
  72. push(@dir, $vhost);
  73.  
  74. my $hostDir = join('/', @dir);
  75. $res{'docRoot'} = $hostDir . '/' . $docRoot;
  76. $res{'logsDir'} = $hostDir . '/' . $logsDir;
  77. $res{'hostDir'} = $hostDir;
  78. #todo dir validation
  79. @dir = split(/\//, $apacheConfigDir);
  80. push(@dir, $sitesAvailable);
  81. push(@dir, $vhost);
  82. $res{'apacheConfig'} = join('/', @dir);
  83. return %res;
  84. }
  85.  
  86. sub createVhost {
  87. my $vhost = shift;
  88. #first create the docRoot
  89. my %vhostInfo = returnVhostPaths($vhost);
  90. informOut("Creating docroot dir: $vhostInfo{'docRoot'}");
  91. mkpath($vhostInfo{'docRoot'});
  92. my $user = getlogin();
  93. my $uid = getpwnam($user);
  94. my $gid = getgrnam($user);
  95. chown $uid, $gid, $vhostInfo{'hostDir'};
  96. chown $uid, $gid, $vhostInfo{'docRoot'};
  97. informOut("Creating log dir: $vhostInfo{'logsDir'}");
  98. mkpath($vhostInfo{'logsDir'});
  99.  
  100. informOut("Site File: $vhostInfo{'apacheConfig'}");
  101. my $vhostContent = << "EOF";
  102. <VirtualHost *:80>
  103. ServerName $vhost
  104. DocumentRoot $vhostInfo{'docRoot'}
  105. <directory $vhostInfo{'docRoot'}>
  106. Options Indexes FollowSymLinks
  107. AllowOverride All
  108. Order allow,deny
  109. Allow from all
  110. </directory>
  111. ErrorLog $vhostInfo{'logsDir'}/error_log
  112. CustomLog $vhostInfo{'logsDir'}/access_log "%h %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-agent}i\\""
  113. LogLevel debug
  114.  
  115.  
  116. EOF
  117. informOut("Creating Vhost...");
  118. open FILE, ">", $vhostInfo{'apacheConfig'} or die $!;
  119. print FILE $vhostContent;
  120. close FILE;
  121. informOut("Adding host $vhost");
  122. open FILE, ">>", '/etc/hosts' or die $!;
  123. print FILE $ipAddress ."\t". $vhost ."\n";
  124. close FILE;
  125. my $output = `/usr/sbin/a2ensite $vhost`;
  126. print $output;
  127. restartApache();
  128. #print $vhostConten t;
  129. }
  130.  
  131. sub restartApache
  132. {
  133. informOut("Restarting apache");
  134. my $output = `/etc/init.d/apache2 restart`;
  135. print $output;
  136. }
  137.  
  138. sub deleteVhost
  139. {
  140. my $vhost = shift;
  141. my %vhostInfo = returnVhostPaths($vhost);
  142. informOut("Removing $vhost from hosts file");
  143. open IN, '< ', '/etc/hosts' or die $!;
  144. my @hostsFile = <IN>;
  145. close IN;
  146. my @contents = grep(!/^127.0.0.1\t$vhost/, @hostsFile);
  147. open FILE, ">", '/etc/hosts' or die $!;
  148. print FILE @contents;
  149. close FILE;
  150. my $output = `/usr/sbin/a2dissite $vhost`;
  151. print $output;
  152. informOut("Removing $vhostInfo{'apacheConfig'} file");
  153. unlink($vhostInfo{'apacheConfig'});
  154. restartApache();
  155. print " manually remove $vhostInfo{'docRoot'}... \n";
  156. }
  157.  
  158. sub informOut {
  159. my $message = shift;
  160. print "$message \n";
  161. }