There's a lot of developers out there who aren't big on the dev op's side of things. I'm one of them. With plenty of other technologies to learn and keep up with it might be easy to overlook areas like virtualisation. And yet by not harnessing the power of this in your workflow, you'll ironically end up spending more time doing the things you're trying to avoid; manually installing server software, configuring dependendies, labourious tasks you've probably done a hundred times before.
So today we're going to take a look virtualisation, and specifically the software Vagrant.
You're probably already familiar with this concept as it's now widely adopted in business and is a common infrastructure basis for web hosting. Simply put, virtualisation involves running software within a virtual environment, which acts like a standalone real computer. To achieve this it uses an allocated amount of the physical hardware's resources (processing power, ram, disk space), differing from a traditional setup where the hardware would have a single operating system that owns everything.
With server virtualisation, you can fire up multiple instances by allocating the host resources to your vm server configurations. In this instance we're interested in a server that can be virtually created within your physical host machine for development.
For companies there's the obvious advantage of reducing physical space required for servers, and virtualisation allows the resources on the physical machines to be used more effectively. But what advantages are there for developers?
Vagrant is only a tool for managing Virtual Machine (VM) environments. So to start with we need the actual VM software, here are three popular options:
I won't delve into the specifics of these as they ultimately achieve the same goal, notable differences include price and performance (not necessarily correlated!). As vagrant fully supports virtualbox and it's free, that's what we'll roll with today.
On linux this is easily done on command line:
sudo apt-get install virtualbox
For windows and mac you can download the executables here: https://www.virtualbox.org/wiki/Downloads
Download and install Vagrant from here https://www.vagrantup.com/downloads.html
On completion, try typing 'vagrant' into a command line to test it has installed properly.
On a command line enter the following:
vagrant init ubuntu/trusty64 vagrant up
You'll probably notice this takes a short while first time round while it downloads, but once complete that's it - you have an up and running virtual box! You can end the box at any time using:
This just initialised what is known as a 'box' - a preconfigured base image with a server setup, which was fired up with the 'up' command. In this instance we created a virtual machine configured for the latest version of Ubuntu. As the box we requested wasn't available it was automatically downloaded.
On completion you'll note you were informed where vagrant was located, and here you will find your Vagrantfile. This marks the root directory of your project and provides the configuration details of your project. If you open this up you'll see near the top the lines:
config.vm.box = "ubuntu/trusty64"
A list of available boxes with different configurations can be found here: https://app.vagrantup.com/boxes/search
Whereas the box we installed was downloaded during the booting process, we could have done this in advance using the following command making it available for re-use in the environment:
vagrant box add ubuntu/trusty64
Let's take a step back and set up our own project.
Create an example directory for your project, cd into it and then type the following command:
This will create a VagrantFile inside your directory. Open this with an editor.
The config defines which box you want to use, update this as defined below to use a ubuntu server configuration, or choose your preferred environment from the box library (https://app.vagrantup.com/boxes/search):
config.vm.box = "ubuntu/trusty64"
You can also use the following lines to specifically dictate a version or url to the box:
# config.vm.box_version = "1.0.0" # config.vm_box_url = "http://path/to/box"
Save, exit then run the following command to SSH into your new environment:
You're now SSH'd into a virtual machine running a Ubuntu configuration. Cancel the SSH connection any time with CTRL+D.
So we've got a virtual machine, but if you still have to manually configure everything then we're not saving ourselves much time. This is where provisioning comes in. Save the following content into a provision.sh file in the same directory as the Vagrantfile:
apt-get update apt-get install -y apache2 if ! [ -L /var/www ]; then rm -rf /var/www ln -fs /vagrant /var/www fi
The above will map /var/www/ to our /vagrant directory. Now edit the Vagrantfile to run this script when it boots:
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/trusty64" config.vm.provision :shell, path: "provision.sh" end
Now when the virtual machine is loaded, it will execute the provision.sh file, which will set up apache2 in your new environment. We'll cover a more comprehensive LAMP configuration in an upcoming article.
Now that we've got a virtual machine configured, how do we go about sharing and accessing it from our host machine? To start with, synced folders allow you to share files between your local machine (host) and your virtual machines (guests), this is great if you want to keep all your development files on the host. By default everything in the folder which your Vagrant file sits in will automatically be shared with the /vagrant directory at the root of your virtual box. Try this:
vagrant up vagrant ssh mkdir /vagrant/html touch /vagrant/html/index.html
You might also want to edit that file and chuck in a 'hello world' for later testing. Finally take a look on your host machine and you'll see the new folder and file has automatically been synced to your vagrant directory.
Great, so now we're sharing files, how about accessing the guest machine over a network? The simplist solution for this is to use port forwarding where you assign ports on the guest machine to share with the host.
Add the following line to your Vagrantfile:
config.vm.network :forwarded_port, guest: 80, host: 8080
Reload vagrant (use the previous 'vagrant up' if it virtual machine isn't still running):
You should now be able to access your guest machine via the host by browsing to http://127.0.0.1:8080 to view your hello world page. Now we're cooking.
Finally, when the work day is done you have three options for powering down:
Suspend: save the current state read to pick up again next time with 'vagrant up' - super fast
Halt: essentially a graceful shutdown ready to reload with 'vagrant up' again, state of the disk is preserved
Destroy: power down and delete everything, disk space and ram are returned to the host but requires the provision process to be re-run next time 'vagrant up' is run