Web Development Environments Using Vagrant on Ubuntu Linux

Setting up Web Development Environments can be an exasperating task. Especially, when you need to work on multiple projects with different dependencies, configurations, library requirements, programming language versions and operating systems. If you have been developing web applications for sometime, then you definitely know the drill.

Vagrant is a tool that helps you in creating and setting up Development Environments quickly in an automated fashion by using virtualization softwares such as VirtualBox and VMware. These environments are then, can be reproduced and redistributed using a single configuration file. To automate the process, Vagrant uses certain provisioning tools like: shell scripts, Chef and Puppet.


A simple installation script:


#save this script as: vagrant_setup.sh
#make it executable using: chmod +x vagrant_setup.sh
#run using: ./vagrant_setup.sh
#or simply run these commands one by one in terminal.

wget -q -O - http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc | sudo apt-key add -

#for ubuntu 12.04 LTS 
sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian precise non-free contrib" >> /etc/apt/sources.list.d/virtualbox.org.list'

#for ubuntu 13.10
#sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian saucy contrib" >> /etc/apt/sources.list.d/virtualbox.list' 
#for ubuntu 13.04
#sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian raring contrib" >> /etc/apt/sources.list.d/virtualbox.list'
#for ubuntu 12.10
#sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian quantal contrib" >> /etc/apt/sources.list.d/virtualbox.list'

sudo apt-get update
sudo apt-get install -y virtualbox-4.3

cd ~/Downloads
wget -O vagrant.deb https://dl.bintray.com/mitchellh/vagrant/vagrant_1.4.3_i686.deb
sudo dpkg -i vagrant.deb

The above script first adds the repository required for the virtualbox-4.3 and then installs the softwares. If you are using a Ubuntu distribution other than Ubuntu 12.04 LTS, use one of the commented options in the script to add the suitable repository.

Vagrant Environment

Vagrant uses a special file named as Vagrantfile to prepare a virtual machine. This file actually defines the global specifications and configurations of a Vagrant Environment. These configurations and specifications are then used to prepare / provision a virtual machine. To set up a Vagrant Environment we use vagrant init command. Let us create a Vagrant Environment called as MyVagrant:

└─•mkdir MyVagrant

└─•cd MyVagrant

└─•vagrant init

When we run vagrant init command Vagrant places a default Vagrantfile inside the directory. This Vagrantfile is shown in the following screenshot:

Creating Web Development Environments Using Vagrant on Ubuntu Linux
Vagrantfile Screenshot

Here is a short list of configuration options that can be defined in a VagrantFile:

  • config.vm.box – the name of the base box to be used to prepare a virtual machine.
  • config.vm.box_url – defines the fall back URL for the base box.
  • config.vm.guest – specifies the type of guest OS.
  • config.vm.hostname – the hostname for the virtual machine.
  • config.vm.provision – used to configure provisioning scripts and type of provisioning.
  • config.vm.synced_folder – specifies the path to the shared folder that should be synced with the host folder.

For a complete list of options and details visit Vagrant Documentation Page.

Vagrant Boxes

Vagrant Boxes are pre-configured and striped down OS images that can be used by Vagrant to clone virtual machines. These OS images usually contain only a small set of packages and some Vagrant specific configurations. Vagrant manages these boxes in a special directory ~/.vagrant.d/boxes/. We can add as many boxes as we want by using vagrant add box URL command. Now, Let us add a box into our vagrant installation:

└─•vagrant box add precise32 http://files.vagrantup.com/precise32.box

This can take some time depending on your Internet connection speed. After the successful completion of the above command, you can confirm your download by visiting ~/.vagrant.d/boxes directory.

A list of Vagrant boxes can be found here.

Booting up

Since our box is downloaded, its time to specify the name of the box inside our Vagrantfile, so that it can clone a virtual machine from this box. For now, our Vagrantfile looks like this:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "precise32"


Now, running the virtual machine is just a matter of executing vagrant up command. The following screenshot shows a sample boot up process:

Creating Web Development Environments Using Vagrant on Ubuntu Linux
Vagrant Up Process Screenshot

Note that after the boot up process, the guest virtual machine will run in the background. We can interact with the machine by using vagrant ssh command which gives us the access to the guest machine’s shell. See the screenshot below:

Creating Web Development Environments Using Vagrant on Ubuntu Linux
Vagrant SSH Shell Screenshot

Quick Tip:
The host folder i.e, MyVagrant will be shared with the guest OS at /vagrant mount point. Whenever, a file will be created inside the host folder, Vagrant will take care of the synchronization. The default mount point can be changed using config.vm.synced_folder configuration property.

Provisioning a Web Development Environment

As I mentioned earlier, Vagrant boxes only contain a minimal set of packages and configurations. And since, Vagrant clones virtual machines from these boxes, our virtual machines will share the same set of packages. But, we can transform these virtual machines into full fledged working environments according to our needs. This is achieved through Provisioning. Vagrant provides us with multiple ways of provisioning a virtual machine: Puppet, Chef, Shell, Docker etc. The most basic provisioning is Shell Provisioning. In this section, we will use the Shell to provision a Web Development Environment.

Updated Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "precise32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"
  config.vm.provision "shell", path: "provision.sh"
  config.vm.network :private_network, ip: ""




# simple vagrant provisioning script
# installs : apache2, php 5.4 and mysql-server and client
# installs : laravel in /vagrant shared folder

# some coloring in outputs.

echo -e "${COLOR}---updating system---${COLOR_RST}"
apt-get update

echo -e "${COLOR}---installing some tools: zip,unzip,curl, python-software-properties---${COLOR_RST}"

apt-get install -y python-software-properties
apt-get install -y zip unzip
apt-get install -y curl

# installig mysql
# pre-loading a default password --> yourpassword
debconf-set-selections <<< "mysql-server mysql-server/root_password password yourpassword"
debconf-set-selections <<< "mysql-server mysql-server/root_password_again password yourpassword"
echo -e "${COLOR}---installing MySql---${COLOR_RST}"
apt-get install -y mysql-server mysql-client

# installing apache2
echo -e "${COLOR}---installing Apache---${COLOR_RST}"
apt-get install -y apache2 

echo -e "${COLOR}---adding php 5.4 ppa---${COLOR_RST}"
add-apt-repository -y ppa:ondrej/php5-oldstable

echo -e "${COLOR}---update again---${COLOR_RST}"
apt-get update

# installing php 5.4
echo -e "${COLOR}---installing php 5.4---${COLOR_RST}"
apt-get install -y php5 libapache2-mod-php5 php5-mcrypt php5-curl php5-mysql

#installing laravel

echo -e "${COLOR}---installing laravel in /vagrant/---${COLOR_RST}"

cd /vagrant

#getting laravel

wget -O laravel.zip https://github.com/laravel/laravel/archive/master.zip
unzip laravel.zip

#rename laravel-master to laravel
mv laravel-master laravel

#remove master.zip
rm laravel.zip

cd laravel

#getting composer
echo -e "${COLOR}---getting composer.phar---${COLOR_RST}"
curl -sS https://getcomposer.org/installer | php

#updating laravel
echo -e "${COLOR}---updating laravel---${COLOR_RST}"
php composer.phar update

echo -e "${COLOR}---laravel installation complete---${COLOR_RST}"
echo -e "${COLOR}run: sudo chmod -R 777 ~/MyVagrant/laravel/app/storage${COLOR_RST}"
echo -e "${COLOR}from host to fix permissions on storage directory!${COLOR_RST}"

# run this command from host OS to fix permissions on storage directory
# sudo chmod -R 777 ~/MyVagrant/laravel/app/storage


cd ~

# setting document root to laravel/public
echo -e "${COLOR}---setting document root to laravel/public/${COLOR_RST}"
sed -i 's#/var/www/\?#/vagrant/laravel/public/#g' /etc/apache2/sites-available/default
a2dissite default && a2ensite default

# enable mod rewrite for apache2
echo -e "${COLOR}---enabling rewrite module---${COLOR_RST}"
if [ ! -f /etc/apache2/mods-enabled/rewrite.load ] ; then
    a2enmod rewrite

# restart apache2
echo -e "${COLOR}---restarting apache2---${COLOR_RST}"
service apache2 restart

# done 🙂
# test your installation by visiting from your host, you will see Laravel logo.

Download provision.sh

Vagrant runs the provisioning scripts when we boot up the virtual machine for the first time i.e, by using vagrant up command. We can also run provisions by using vagrant provision command on a running Environment.

In the Vagrantfile, provisioning method is specified as shell by using the config.vm.provision property. The path to the provisioning script provision.sh is also specified. The config.vm.network property is used to specify an IP address from the private space.

The provisioning script provision.sh, simply installs MySQL Server and Client, Apache 2.2 and PHP 5.4. As a bonus, it also installs a copy of Laravel. You can test your installation by entering in your browser.

Creating Web Development Environments Using Vagrant on Ubuntu Linux
Laravel and Webserver Test Screenshot