Automatic Website Configuration in Apache

The simple life of simple websites on an Apache server.

I had to set up a server for a client hosting 1000+ small websites. Each site is just a small html page with an iframe, but the process of configuring virtual hosts in Apache needed to be automated.

The client was asked to upload sites to the server over ftp and name the folders after the full site names. On the server side, pure-ftpd with a virtual user was configured. After logging in, the client lands in the /var/www/html folder, where they create a folder named after the site and upload the files into it.

After that, server-side magic kicks in and the site becomes available by the will of magical bash.

For this, a template was created in the /etc/httpd/conf.d/ folder:

/etc/httpd/conf.d/template
<VirtualHost *:80>
  ServerName websiterepl
  ServerAlias www.websiterepl
  DocumentRoot /var/www/html/websiterepl

  LogLevel warn
  ErrorLog /var/log/httpd/websites/error.log
  CustomLog /var/log/httpd/websites/access.log combined

  <Directory /var/www/html/websiterepl>
    Options +ExecCGI -Indexes +FollowSymLinks +MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>
</VirtualHost>

After that, the following script processes the contents of /var/www/html/ and creates virtual hosts in the apache config for every folder.

/usr/local/bin/make_vhosts
#!/bin/bash

do_websites () {
for f in $(ls /var/www/html/);
do
  sed 's/websiterepl/'"$f"'/g' /etc/httpd/conf.d/template >> /etc/httpd/conf.d/websites.conf
  echo "" >> /etc/httpd/conf.d/websites.conf
done
}

make_logs() {
for folder in $(grep ErrorLog /etc/httpd/conf.d/websites.conf |awk '{print $2}' |sed 's/error.log//g');
do
  if [ ! -d $folder ];
  then
    mkdir -p $folder;
  fi
done
}

if [ "$1" == "force" ]
then
  rm -f /etc/httpd/conf.d/websites.conf
  do_websites
  make_logs
  service httpd reload
else

servernames=$(grep ServerName /etc/httpd/conf.d/websites.conf |wc -l)
folders=$(ls /var/www/html |wc -l)

if [ "$folders" != "$servernames" ]
then
  rm -f /etc/httpd/conf.d/websites.conf
  do_websites
  make_logs
  service httpd reload
fi
fi

Using crontab to make the script run every 15 minutes.

*/15 * * * * /usr/local/bin/make_vhosts_nginx 2>&1 >> /dev/null

In principle, the script itself already checks the number of virtual hosts against the number of folders in /var/www/html, so it could just as well run every 5 minutes.

The script can be forced to run using the force flag.

Categories:

Updated: