Working with Virtual Hosts in Scotch Box Pro

I have been a great fan of Scotch Box. If you had not heard about it, it's a light-weight Vagrant LAMP Stack that has a huge load of awesomeness in it. It is frequently kept up to date by Nicholas Cerminara. So, that's too good to be true, then what are all its features?

Features of Scotch Box

Some of the awesome Pro features include:

  • New OS: Ubuntu-17.10!
  • New PHP: PHP 7.2!
  • New Apache: 2.4.29
  • New nginx: 1.13.8
  • New Ruby via RVM: 2.5.0
  • New Node via NVM: 8.9.4
  • New Build Scripts
  • Fixes a MongoDB and PHP bug
  • Laravel routing works out of the box with the NGINX version
  • Adds Drush (Launcher) even though you should do this through Composer these days
  • Updated WP-CLI version
  • Generally WAY higher versions of everything else

You still have great other features like creating and publishing your own box. Or leave that, you can customise your Message of the Day and show something like this:

That's super cool right? So what are you waiting for? Go ahead and purchase the Scotch Box Pro! It's a one time purchase and you get to have unlimited downloads!

Workaround for vHosts Problem with Scotch Box Pro

The recent release of Scotch Box Pro, as is currently is unable to create the Virtual Hosts based on the information given in the website: Multiple Domains (Virtual Hosts) as the required scotchbox.local.conf is not bundled with the virtual machine.

The best test for this is, when you try to run the provisioner, you get to see this error:

There are three ways of fixing this:

  1. Manually SSHing into the machine, creating the file scotchbox.local.conf from default.conf and running the Shell Provisioners.
  2. Creating the file scotchbox.local.conf using the Shell Provisioner and working the way out for the other domains.
  3. Creating the Virtual Hosts configurations inline using the Shell Provisioner.

I'll go in detail on each method and you choose the best one for you. I chose the first method of copying the contents manually, if this helps.

Method 1: Manually creating scotchbox.local.conf

The first step is to SSH into your Vagrant machine by getting into your Vagrant by using the following command:

vagrant ssh  

This will get you inside the Vagrant box and you will be logged in with the user vagrant and you will be in the home directory:

vagrant@scotchbox:~$  

Try editing (or creating) the file scotchbox.local.conf using the following command:

vagrant@scotchbox:~$ vim /etc/apache2/sites-available/scotchbox.local.conf  

Once you are in, you will be in a VIM terminal. Please press I key on your keyboard, so that it goes to INSERT mode. You can confirm it by looking at the bottom of the page and it should say:

-- INSERT --

Once you are in INSERT mode, please update the file with the following contents:

<VirtualHost *:80>  
    ServerAdmin webmaster@localhost
    ServerName scotchbox.local
    ServerAlias www.scotchbox.local
    DocumentRoot /var/www/public
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>  

Now save the file by exactly pressing Esc key, then : key and type wq making it look like this in the footer and press Enter.

:wq

You will be returned back to your command line and your terminal might look like this:

vagrant@scotchbox:~$ vim /etc/apache2/sites-available/scotchbox.local.conf  
vagrant@scotchbox:~$  

Please exit out of the terminal by typing in exit and return to your command line in your host computer. At this time, you have to update your Vagrantfile to look something like this:

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|  
    config.vm.box = "scotch/box-pro"
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.hostname = "scotchbox"
    config.vm.synced_folder ".", "/var/www", :nfs => { :mount_options => ["dmode=777","fmode=666"] }
    config.vm.provision "shell", inline: <<-SHELL
        ## Only thing you probably really care about is right here
        DOMAINS=("praveen.box")
        ## Loop through all sites
        for ((i=0; i < ${#DOMAINS[@]}; i++)); do
            ## Current Domain
            DOMAIN=${DOMAINS[$i]}
            echo "Creating directory for $DOMAIN..."
            mkdir -p /var/www/$DOMAIN
            echo "Creating vhost config for $DOMAIN..."
            sudo cp /etc/apache2/sites-available/scotchbox.local.conf /etc/apache2/sites-available/$DOMAIN.conf
            echo "Updating vhost config for $DOMAIN..."
            sudo sed -i s,scotchbox.local,$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            sudo sed -i s,/var/www/public,/var/www/$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            echo "Enabling $DOMAIN. Will probably tell you to restart Apache..."
            sudo a2ensite $DOMAIN.conf
            echo "So let's restart apache..."
            sudo service apache2 restart
        done
    SHELL
end  

Now try running vagrant provision command to perform the provisioning. The provisioning starts again and you will find the results being positive.

Method 2: Using Shell Provisioner to create the file scotchbox.local.conf

This method doesn't make you go into the SSH, but also beware, this method has not been tested with all the computers. The only thing you will be doing is to edit the Vagrantfile to include the creation of scotchbox.local.conf on the fly using the provisioners and copying them for your domains.

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|  
    config.vm.box = "scotch/box-pro"
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.hostname = "scotchbox"
    config.vm.synced_folder ".", "/var/www", :nfs => { :mount_options => ["dmode=777","fmode=666"] }
    config.vm.provision "shell", inline: <<-SHELL
        ## Only thing you probably really care about is right here
        DOMAINS=("praveen.box")
        ## Create the scotchbox.local.conf inline.
        echo "Creating vhost config for scotchbox.local..."
        cat >/etc/apache2/sites-available/scotchbox.local.conf <<EOL
<VirtualHost *:80>  
    ServerAdmin webmaster@localhost
    ServerName scotchbox.local
    ServerAlias www.scotchbox.local
    DocumentRoot /var/www/scotchbox.local
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>  
EOL  
        ## Loop through all sites
        for ((i=0; i < ${#DOMAINS[@]}; i++)); do
            ## Current Domain
            DOMAIN=${DOMAINS[$i]}
            echo "Creating directory for $DOMAIN..."
            mkdir -p /var/www/$DOMAIN
            echo "Creating vhost config for $DOMAIN..."
            sudo cp /etc/apache2/sites-available/scotchbox.local.conf /etc/apache2/sites-available/$DOMAIN.conf
            echo "Updating vhost config for $DOMAIN..."
            sudo sed -i s,scotchbox.local,$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            sudo sed -i s,/var/www/public,/var/www/$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            echo "Enabling $DOMAIN. Will probably tell you to restart Apache..."
            sudo a2ensite $DOMAIN.conf
            echo "So let's restart apache..."
            sudo service apache2 restart
        done
    SHELL
end  

After saving the file, try running vagrant provision command to perform the provisioning. The provisioning starts again and you will find the results being positive.

Method 3: Dynamically creating the vHosts without scotchbox.local.conf

This method doesn't make you go into the SSH as well, but also beware, this method has not been tested with all the computers. The only thing you will be doing is to edit the Vagrantfile to include the creation of domain's .conf on the fly using the provisioners.

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|  
    config.vm.box = "scotch/box-pro"
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.hostname = "scotchbox"
    config.vm.synced_folder ".", "/var/www", :nfs => { :mount_options => ["dmode=777","fmode=666"] }
    config.vm.provision "shell", inline: <<-SHELL
        ## Only thing you probably really care about is right here
        DOMAINS=("praveen.box")
        ## Loop through all sites
        for ((i=0; i < ${#DOMAINS[@]}; i++)); do
            ## Current Domain
            DOMAIN=${DOMAINS[$i]}
            echo "Creating directory for $DOMAIN..."
            mkdir -p /var/www/$DOMAIN
            echo "Creating vhost config for $DOMAIN..."
            cat >/etc/apache2/sites-available/$DOMAIN.conf <<EOL
<VirtualHost *:80>  
    ServerAdmin webmaster@localhost
    ServerName ${DOMAIN}
    ServerAlias www.${DOMAIN}
    DocumentRoot /var/www/${DOMAIN}
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>  
EOL  
            echo "Updating vhost config for $DOMAIN..."
            sudo sed -i s,scotchbox.local,$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            sudo sed -i s,/var/www/public,/var/www/$DOMAIN,g /etc/apache2/sites-available/$DOMAIN.conf
            echo "Enabling $DOMAIN. Will probably tell you to restart Apache..."
            sudo a2ensite $DOMAIN.conf
            echo "So let's restart apache..."
            sudo service apache2 restart
        done
    SHELL
end  

After saving the file, try running vagrant provision command to perform the provisioning. The provisioning starts again and you will find the results being positive.

I hope this article was helpful to you. Pen down your comments, if you have any. All credits for building such an awesome thing goes to Nick! 😁