Automating Virtual Host setup on your server
Published: 2020-11-04 14:04:11

Are you also one of those who frequently need to setup VHosts in order to test,create etc new sites and you feel doing the whole process again and again is time consuming and well.. BORING? Then this article is for you!

**Note:** The script used in this article is written for any **Linux** distro with **Apache** server, but you may still get a general idea of how to use it for your requirements.  

Here we will create a simple bash script to automate the whole vhost setup process which includes:

* Creating a new folder for your website.
* Creating configuration files for the website.
* Configuring the `hosts` file and
* Enabling the vhost.

### Creating template files
Before we start working on our script we will need these template files which we use in the setup:
* A template `conf` file to create configuration for the vhost.
* A template `index.html` file for default homepage of our newly created vhost

This is how my template files looks like:
**default-index.html**
```html
 <html>
   <head>
     <title>Home|New Virtual Host</title>
   </head>
   <body>
        <h1>Welcome!</h1> 
        You just created a new virtual host!<br>
        Go ahead and add some files in your brand new vhost
   </body>
 </html>
```

**default-vhost.conf**
```
<VirtualHost *:80>
        ServerName 127.0.0.x
        ServerAlias example.local
        ServerAdmin admin@example.local
        DocumentRoot /var/www/example.local

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

You can create similar files based on your requirements.

Now let's get started with the script.

### Getting `sitename` and `host` from command line
Let's start by getting the input parameters as command line arguments. We will use the flags:
* `-s`: for sitename
* `-h`: for host


We will also use a flag `-d` (optional) in case user wants to create a new project directory for the vhost.

We will use `getopts` to get the arguments, if you are not familiar with `getopts` you can check out [this article](https://dev.to/shriaas2898/taking-command-line-arguments-using-flags-in-bash-121).

This is how we can take input from command line:
```bash
while getopts s:h:d flag
do
case "${flag}" in
                s) sitename=${OPTARG}
                        ;;
                h) host=${OPTARG}
                         ;;
                d) createdir=1
                        ;;
 echo "Added entry in hosts file"
               *) echo "Invalid option: -$flag" ;;
        esac
done
```
We are storing the values we got from input in `sitename` and `host` variable and setting `createdir` to 1.

### Creating and configuring project directory
Next we will create a folder in `/var/www` and copy our `default-index.html` file in that folder:

```bash
if [[ $createdir -eq 1 ]]
then
  mkdir /var/www/$sitename
  cp default-index.html /var/www/$sitename/index.html
```

We are checking if user has specified the `-d` flag or not, you can remove the condition if you always want create a new directory for your vhost. You can also skip this step depending on your requirement.

Now that we have created the directory let's change the owner to current logged-in user:
```bash 
  chown $SUDO_USER:$SUDO_USER /var/www/$sitename
```
This is because only the super user has permissions to create files and folders in `var/www`, so we are changing the owner of the folder so that the current user will have full control over the folder.


This script needs to be run using sudo, `$SUDO_USER` contains user name of user which is executing the script using `sudo`.

 
Now let's change the permission for
```bash
  chmod 755 /var/www/$sitename
fi

```
### Creating configuration files
Now we will create the `conf` file for our site in `/etc/apache2/sites-available/` using or default template:
```bash
cd /etc/apache2/sites-available/
cp default-vhost.conf $sitename.conf
sed -i "s/example.local/$sitename/g" $sitename.conf
sed -i "s/127.0.0.x/$host/g" $sitename.conf
```
Here `sed` or `stream editor` is a command line tool for editing, we are using `sed` to replace *example.local* with `$sitename` and *127.0.0.x* with `$host` in our conf file.

### Configuring hosts file
Currently your `/etc/host` must look like something like this :
```
127.0.0.1       localhost
.
.
.

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
.
.
.
```

We want to add the host and sitename before `# The following lines are desirable...` line. For this we will once again use the `sed`:
```bash
sed -i "0,/# The following lines are desirable for IPv6 capable hosts/s/^# The following lines are desirable.*/$host       $sitename\n&/" /etc/hosts
```
### Enabling virtual host and restarting the server
Now let's enable our vhost using `a2ensite` command and reload apache:

```bash
a2ensite $sitename.conf
systemctl reload apache2
echo "All done! Visit your newly created virtual host at https://example123.local"
```
And that's it! Phew! We just created a simple script to automate vhost configuration. Let's go ahead and execute it:

```
sudo ./create-conf.sh -s example123.local -h 127.0.0.12 -d

All done! Visit your newly created virtual host at https://example123.local
```
Let's visit our newly created virtual host
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6otf0jd6hr6mbdo3d1d1.png)

Here is how our full script looks like:

```bash
#!/bin/bash
while getopts s:h:d flag
do
case "${flag}" in
                s) sitename=${OPTARG}
                        ;;
                h) host=${OPTARG}
                         ;;
                d) createdir=1
                        ;;
                *) echo "Invalid option: -$flag" ;;
        esac
done
# Create and configure folder in `/var/www` if option if option selected
if [[ $createdir -eq 1 ]]
then
  mkdir /var/www/$sitename
  echo "Folder /var/www/$sitename created"
  # Creating dummy landing page
  cp default-index.html /var/www/$sitename/index.html
  echo "Intitialized with index page"

  # Changing owner and permission of the folder
  chown $SUDO_USER:$SUDO_USER /var/www/$sitename
  chmod 755 /var/www/$sitename
  echo "Modified permissions and owner"
fi
# Creating configuration files
cd /etc/apache2/sites-available/
cp default-vhost.conf $sitename.conf
sed -i "s/example.local/$sitename/g" $sitename.conf
sed -i "s/127.0.0.x/$host/g" $sitename.conf
echo "Configuration files created"

# Configuring hosts file
sed -i "0,/# The following lines are desirable for IPv6 capable hosts/s/^# The following lines are desirable.*/$host       $sitename\n&/" /etc/hosts
echo "Added entry in hosts file"

# Enabling virtual host and restarting the server
a2ensite $sitename.conf
systemctl reload apache2
echo "Restarted apache"
echo "All done! Visit your newly created virtual host at https://$sitename"

```
## Final Thoughts
Though this script may not fully work with your requirement you can definitely get an idea of how to make one for yourself do let me know in the comments what you think about it!

## References:
[Setting up Virtual Host on Ubuntu 20 ](https://dev.to/shriaas2898/setting-up-virtual-host-on-ubuntu-20-joe)
[Taking command line arguments using flags in bash ](https://dev.to/shriaas2898/taking-command-line-arguments-using-flags-in-bash-121)
[Stream Editor to insert line](https://stackoverflow.com/questions/30386483/command-to-insert-lines-before-first-match)
[How to use sed to find and replace text in files in Linux / Unix shell](https://www.cyberciti.biz/faq/how-to-use-sed-to-find-and-replace-text-in-files-in-linux-unix-shell/)