Speed up Vagrant Provisioning with vagrant-cachier

Joe • November 11, 2013

linux vagrant devops linux provisioning vagrant

At my day job I work on a proprietary CMS written in PHP. I've been working on building our Vagrant box to allow our developers to have local dev environments without us having to use resources on or live server or have to have our own machines configured to run the CMS. Since I can't show you that box, but found a cool way to cut down the ‘vagrant up' time...

I'm going to show you this box that MidsouthMakers uses to develop our WordPress site in. Feel free to clone that box and follow along. A normal ‘vagrant up' command to ready to use box is around 8:30-9:00 minutes. As you can tell from the Vagrantfile, I'm only giving the box 1 core and 512mb of RAM. The machine I tested this on is my day to day work laptop running a Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz, 8 gigs of RAM, and  it's running Ubuntu 13.10.

To benchmark the time gains of caching, I did a vagrant up before I installed / enabled anything extra. This is what you should see out of the box on a comparable system: 8 minutes and 33 seconds. That's a bit of time to wait for everything to provision.

Enter vagrant-cachier. vagrant-cachier is a plugin that you can install and enable for a box that caches as much as it can. From the README:

Under the hood, the plugin will hook into calls toVagrant::Builtin::Provision during vagrant up / vagrant reload and will set things up for each configured cache bucket. Before halting the machine, it will revert the changes required to set things up by hooking into calls toVagrant::Builtin::GracefulHalt so that you can repackage the machine for others to use without requiring users to install the plugin as well.

Cache buckets will be available from /tmp/vagrant-cachieron your guest and the appropriate folders will get symlinked to the right path after the machine is up butright before it gets provisioned. We could potentially do it on one go and share bucket’s folders directly to the right path if we were only using VirtualBox since it shares folders after booting the machine, but the LXC provider does that as part of the boot process (shared folders are actually lxc-start parameters) and as of now we are not able to get some information that this plugin requires about the guest machine before it is actually up and running.

Please keep in mind that this plugin won’t do magic, if you are compiling things during provisioning or manually downloading packages that does not fit into a “cache bucket” you won’t see that much of improvement.

Clear as mud right? Hopefully some of that made sense. If you're like me and it kinda made sense: that's good enough. The important thing to understand is that you're saving bandwidth by not downloading everything each time. There is more going on than that, but I won't pretend to be the expert.

So how did our box do? Well the first run was 8:33. After we installed vagrant-cachier and enabled it in our Vagrantfile, we do vagrant up again and this time it took 8 minutes and 35 seconds. Two seconds faster. Ok, so lets vagrant destroy and try this again. Now we should be using the cached data. Running vagrant up again only takes 5 minutes and 13 seconds, shaving 3:20 off our time. That is a pretty nice time savings. Just to try this again to make sure it's not a fluke, we vagrant destroy and vagrant up again. This time it takes 5 minutes and 2 seconds. Still very close and much better than the original 8:33 it took.

For further reading and to better understand what's actually happening check out the github project and the author's own blog post about the plugin. Thanks to Fábio Rehm & the others in #vagrant on Freenode that chimed in when I came looking for help.