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
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