Creating a new Apache virtual host is something that’s done for every web project. It’s not a complicated process, but it can be simplified further by creating a bash script to automate the process. My script will update the Apache vhosts, add the new site to the hosts file, create the site directory if it doesn’t exist, and restart Apache. This script could be greatly expanded or changed depending on your needs. The script needs to be run as sudo since it updates the hosts file.

 

Usage

To use the script simply use the following command

sudo ./addvhost.sh -u newsite.local -d mynewsite/web

 

The Vhost Bash Script File

Create a script file named addvhost.sh

#!/bin/bash

# permissions
if [ "$(whoami)" != "root" ]; then
	echo "Root privileges are required to run this, try running with sudo..."
	exit 2
fi

current_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
hosts_path="/etc/hosts"
vhosts_path="/etc/apache2/sites-available/"
vhost_skeleton_path="$current_directory/vhost.skeleton.conf"
web_root="/var/www/"


# user input passed as options?
site_url=0
relative_doc_root=0

while getopts ":u:d:" o; do
	case "${o}" in
		u)
			site_url=${OPTARG}
			;;
		d)
			relative_doc_root=${OPTARG}
			;;
	esac
done

# prompt if not passed as options
if [ $site_url == 0 ]; then
	read -p "Please enter the desired URL: " site_url
fi

if [ $relative_doc_root == 0 ]; then
	read -p "Please enter the site path relative to the web root: $web_root_path" relative_doc_root
fi

# construct absolute path
absolute_doc_root=$web_root$relative_doc_root

# create directory if it doesn't exists
if [ ! -d "$absolute_doc_root" ]; then

	# create directory
	`mkdir "$absolute_doc_root/"`
	`chown -R $SUDO_USER:staff "$absolute_doc_root/"`

	# create index file
	indexfile="$absolute_doc_root/index.html"
	`touch "$indexfile"`
	echo "<html><head></head><body>Welcome!</body></html>" >> "$indexfile"

	echo "Created directory $absolute_doc_root/"
fi

# update vhost
vhost=`cat "$vhost_skeleton_path"`
vhost=${vhost//@site_url@/$site_url}
vhost=${vhost//@site_docroot@/$absolute_doc_root}

`touch $vhosts_path$site_url.conf`
echo "$vhost" > "$vhosts_path$site_url.conf"
echo "Updated vhosts in Apache config"

# update hosts file
echo 127.0.0.1    $site_url >> $hosts_path
echo "Updated the hosts file"

# restart apache
echo "Enabling site in Apache..."
echo `a2ensite $site_url`

echo "Restarting Apache..."
echo `/etc/init.d/apache2 restart`

echo "Process complete, check out the new site at http://$site_url"

exit 0

 

Require Sudo

The first part of the script requires that the command be run as sudo with root privileges, and exits if not. This is required to update the hosts file.

# permissions
if [ "$(whoami)" != "root" ]; then
	echo "Root privileges are required to run this, try running with sudo..."
	exit 2
fi

 

Configuration

The next section is all configuration

current_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
hosts_path="/etc/hosts"
vhosts_path="/etc/apache2/sites-available/"
vhost_skeleton_path="$current_directory/vhost.skeleton.conf"
web_root="/var/www/"

 

User Input

I have allowed the user to pass in the site url and doc root using command options or via prompts if the options are missing. To allow options I’ve done the following.

# user input passed as options?
site_url=0
relative_doc_root=0

while getopts ":u:d:" o; do
	case "${o}" in
		u)
			site_url=${OPTARG}
			;;
		d)
			relative_doc_root=${OPTARG}
			;;
	esac
done

To prompt the user if the options were not passed I used the read command.

# prompt if not passed as options
if [ $site_url == 0 ]; then
	read -p "Please enter the desired URL: " site_url
fi

if [ $relative_doc_root == 0 ]; then
	read -p "Please enter the site path relative to the web root: $web_root_path" relative_doc_root
fi

 

Create the Doc Root

The script will create the doc root directory if it doesn’t exist. If it does exist it will bypass this step.

# construct absolute path
absolute_doc_root=$web_root$relative_doc_root

# create directory if it doesn't exists
if [ ! -d "$absolute_doc_root" ]; then

	# create directory
	`mkdir "$absolute_doc_root/"`
	`chown -R $SUDO_USER:staff "$absolute_doc_root/"`

	# create index file
	indexfile="$absolute_doc_root/index.html"
	`touch "$indexfile"`
	echo "<html><head></head><body>Welcome!</body></html>" >> "$indexfile"

	echo "Created directory $absolute_doc_root/"
fi

 

Update Vhosts

The next step is to update the vhost by adding/replacing the vhost file in the sites-available directory. The first part opens the skeleton file and replaces some placeholders with the site url and absolute path to the doc root. The second part adds/replaces the the vhosts file with the new content.

# update vhost
vhost=`cat "$vhost_skeleton_path"`
vhost=${vhost//@site_url@/$site_url}
vhost=${vhost//@site_docroot@/$absolute_doc_root}

`touch $vhosts_path$site_url.conf`
echo "$vhost" > "$vhosts_path$site_url.conf"
echo "Updated vhosts in Apache config"

 

Update Hosts File

The hosts file also needs to be updated, the next part of the script does this.

# update hosts file
echo 127.0.0.1    $site_url >> $hosts_path
echo "Updated the hosts file"

 

Enable the Site and Restart Apache

To complete the process the new site needs to be enabled and Apache needs to be restarted.

# restart apache
echo "Enabling site in Apache..."
echo `a2ensite $site_url`

echo "Restarting Apache..."
echo `/etc/init.d/apache2 restart`

 

Vhost Skeleton File

This script makes use of the following vhost skeleton file, this can be updated to suit your needs.

# @site_url@
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot "@site_docroot@"
    ServerName @site_url@
    ServerAlias www.@site_url@
    ErrorLog "logs/@site_url@-error_log.log"
    CustomLog "logs/@site_url@-access_log.log" common
    <Directory "@site_docroot@">
        Require all granted
        AllowOverride All
  </Directory>
</VirtualHost>

 

Make the File Executable

Finally, make the file executable using the following command.

chmod u+x /path/to/script/addvhost.sh

One comment on “Bash Script to Create Apache Virtual Hosts

  1. Mirko says:

    I’ve added the possibility to choose the skeleton filename as parameter

    while getopts “:u:d:s:” o; do
    case “${o}” in
    u)
    site_url=${OPTARG}
    ;;
    d)
    relative_doc_root=${OPTARG}
    ;;
    s)
    vhost_skeleton_path=”$current_directory/${OPTARG}.skeleton.conf”
    ;;
    esac
    done

    and made a skeleton for symfony with the new apache 2.4 syntax

    # @site_url@

    ServerName @site_url@
    DocumentRoot “@site_docroot@/web”

    AllowOverride All
    Require all granted

    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]

    # uncomment the following lines if you install assets as symlinks
    # or run into problems when compiling LESS/Sass/CoffeScript assets

    Options FollowSymlinks

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

Comments are closed.