What is virtualization and Vagrant?
Virtualization software has been around for a while. It allows a user to run a virtual instance of a physical machine. This allows for things like running a Windows machine from a Mac or Linux machine. Many people use virtualization to run virtual desktop environments. In fact, whenever I have to debug issues with Internet Explorer compatibility, I typically boot up a relevant Windows virtual machine. However, I'm primarily interested in virtualizing server environments.
Virtualizing server environments allows you to have a standardized development environment used by your team members. This alleviates problems that arise from one person developing on a MAMP stack versus a WAMP stack, XAMPP stack, GRAMP stack, etc. You may be wondering, "What problems could possibly arise from this?" Well, if you know nothing about MAMP, and a team member has a problem with MAMP, they are on their own in resolving their issue. If everyone uses MAMP, then there is consistency between members, and some members may be able to help. However, MAMP sucks. Everyone should consider using the same stack that will be serving up your precious requests on staging and production.
This post is focused on virtualizing server environments with Vagrant and VirtualBox. For those unfamiliar, VirtualBox is a virtualization software. It configures, starts and runs virtual machines. Vagrant is a wrapper around VirtualBox, and as of its 1.1.x release, can now be used with VMWare if desired. Vagrant's slogan is "Development environments made easy." I think a better suiting title would be "Virtualization abstracted," because in my six months of using Vagrant, I only found it "easy" once I completely understood its configuration, as well as the thing it abstracts, VirtualBox.
Initial thoughts
Here is the story of my adventures with Vagrant. I wanted to provide a virtualized LAMP stack that resembled what our team uses for development and staging servers. So, I found a CentOS 5.8 box online at http://www.vagrantbox.es. I configured Vagrant to import said box, and all was well. I had a VM running!
So with Vagrant you create a Vagrantfile that serves as your configuration for a given machine or set of machines. You then run vagrant up
, and it downloads a box from a configured URL if it needs to. Otherwise it clones the already downloaded box for use with this new virtual machine.
Then it moves on to configuring the machine's hardware specs like memory, CPU, etc, and then the machine is booted. After that, networking and shared folders are handled, and finally, any provisioner you specify is run. A provisioner configures all the users, packages, files, and services, on that box. A provisioner can be as simple as shell scripts, or advanced as puppet or chef. For me, that required taking up puppet, which is another blog post in itself.
Vagrant allows for shared folders between the host and the guest machines. This is great, as it allows developers to use whatever tools they need to modify code. By default, Vagrant mounts the directory that the Vagrantfile is in to /vagrant on the guest machine, using VirtualBox's "shared folder" functionality.
Vagrant woes
So I ran my first virtualized development environment using Vagrant. Everything looked great, but page loads were unbearably slow. I looked to the docs, and haphazardly deduced that the default "shared folder" functionality is not performant enough for use with Drupal. So I needed to go the NFS route of sharing folders.
Well, in order to do that, you need NFS support on the guest machine. I simply installed the proper package, and was set. Oh, and you need to run the host machine in a "host-only" networking mode, which is not stated in the docs. If you forget this fact, there's at least a pretty straightforward error thrown, pointing you in the right direction.
Ok, so then I read the docs on PrivateNetworking, added the necessary config, and rebooted the machine. I started browsing the dev site again, and page loads were finally reasonable. "Hurray," I thought. I went to go grab some food.
When I got back, I sat down at my machine and experienced timeouts for all requests. So I thought I'd SSH into the box and take a peek, but I couldn't. What a freaking nightmare! I rebooted the machine, SSH'd into the box and watched top. I saw an insane load average and my eyes bled. I rebooted the machine, moved on to other pressing work, and then returned. Still the timeouts persisted. I rebooted the machine again, and immediately started requesting pages. I got served. Pages.
Frustrated, I went to the Vagrant IRC channel to ask for support. There I found little help, but did receive a tip from Steven Merrill. Adding divider=10 to the kernel section in /etc/grub.conf on the guest. "Uh... okay," I thought. It actually worked! I traced this back to a VirtualBox Troubleshooting page which mentioned high server load. This is not development environments made easy.
Then VirtualBox had an update. I upgraded and found that shared folders weren't mounting. This made the machine practically useless for me, as my entire codebase lived in a shared folder. So I found that I needed to update VirtalBox Guest Additions on the guest. Nowhere was this documented, except for a few scattered blog posts.
I then found a Vagrant plugin that automatically updates guest additions upon booting the VM. You can install it via vagrant plugin install vagrant-vbguest
. However, the plugin assumes that you actually installed the packages needed to upgrade guest additions, which I did not. Those packages vary from distro to distro, but I found the ones I needed. I installed them, and repackaged the box so as not to lose these critical packages. This is not development environments made easy.
Then Vagrant 1.1 came out, and configuration syntax was completely changed. The old syntax still worked, but there was no mention of if and/or when it would get chopped by the deprecation axe. So I learned the new syntax, which wasn't at all too difficult, but it certainly was not development environments made easy.
Abstraction is a good thing. Vagrant abstracts VirtualBox so that you don't have to click through a crazy GUI to get a virtual machine up and running. In doing so, it frees the user from even having learn what all of the crazy options in VirtualBox do, such as what chipset to emulate, or if it should Enable PAE/NX. However, being freed from complexity can easily turn into being disenfranchised when the abstracted thing doesn't work as expected.
On Abstraction
The vehicle you drive abstracts the internals into a pleasant user interface of pedals and maybe a clutch and shifter. When a car breaks down, it is frustrating because unless you completely understand the car's internals and have the tools to fix your broken car, you rely on mechanics to fix it. You can't just step on the pedals in some sort of "fix me" special sequence and expect anything to happen besides feeling foolish.
In the case of software abstraction, not much changes except for a lack of mechanics to turn to. You certainly have more power to fix it yourself, but that assumes you have the tools and the knowledge to do so.
All of that to say, I really do enjoy using Vagrant and I absolutely am behind the idea of virtualized development environments, but it's certainly a journey, and not as easy as it appears. While this article probably seems ranty, it's really just an expression of my frustration at using a fairly new technology, and not having the tools and knowledge to fix my abstracted machine.
I think the solution to this particular problem with Vagrant is building a stronger community of users. Besides the GitHub issue queue and Google Group, the Vagrant IRC channel is as good as it gets in terms of support, and if you search for help you'll only find blog posts like these scattered about, instead of a community run forum or something of that nature. For what it's worth, I plan on organizing a Vagrant BoF at DrupalCon Portland.
For now, I feel at ease with Vagrant and I love what it provides. For anyone looking to standardize the development environments of your team's members, I certainly recommend giving a Vagrant a shot, with the caveat of Vagrant not being "development environments made easy," but rather "abstracted
virtualization."