Why I'm (gradually) using Vagrant for all the things

A few years back when I discovered how to use fabric to automate web site deployment it was like a switch got flicked on in my head. Ever since I freak out when I catch people manually copying files over FTP (well... sometimes.) I figure if it's automated, it's consistently repeatable and repeatedly consistent.

Separate to that I've relied on a single trusty instance of Ubuntu 12.04 running as a VirtualBox VM to do my web development. That image gets carted from machine to machine, it's where this blog gets built, and it's got nearly every web project I've built in the last few years running on it... Which can get a little messy, there's a lot of virtual hosts, a pile of python virtualenvs, and node cruft littered all over.

But I've seen the light, and the light looks a lot like Vagrant. Vagrant gets my projects another step towards being consistently repeatable, but this time it's about having a consistent development environment for entire teams.

For the uninitiated, Vagrant is a tool which lets you create virtual dev environments using virtualbox / VMWare / etc. with all the information on how the environment was set up (say, it was a default Ubuntu 12.04 install with apache put in on top) stored in a couple of text files which you commit in with the code. The end game is, anybody who can check the code out can run the exact same dev environment I have, and it only takes them one command.

I'd only played a little with vagrant in the past, but recently started on a web job where it was a perfect fit. I needed to make some updates to a web application someone else built, and the original developer had kindly written up some instructions to get a local dev environment running. But... It was a little involved, and OS X specific.

The existing instructions recommended using a prebuilt OS X Apache/MySQL/PHP stack called MAMP, but there's also some parts which require a socket.io server. The database needed to be configured in a certain way and populated with data from an Amazon EC2 staging environment (copied over PHPMyAdmin), and there were some other manual tasks interacting with the staging environment to fetch content over rsync.

It's a pretty typical situation for a web developer to find themselves in, but in theory you only need to get things running on your environment once and then you're all good to develop 'til the cows come home. It's exactly what I would have done pre-vagrant, but it starts to fall apart a bit when you have multiple developers. But since I needed to set up my dev environment anyway I figured this would be a good chance to play some more with Vagrant, and that way the dev side of things would scale a little better in the future.

My first real run in with vagrant isn't very complicated: I've just got the default vagrant config file with a couple of lines changed, and a 70-ish line bootstrap shell script. When anybody runs vagrant up, vagrant fetches the correct base image from the vagrant file (Ubuntu 12.04), sets up the networking, and then "provisions" the system by running my bootstrap.sh. The bootstrap script is where the main work happens: It runs apt-get update, and then installs and configures apache, PHP, MySQL, and Node. Then it sets up private keys and signatures so it can ssh to the staging server, dump the remote MySQL database straight into the dev environment and bring down any content files it requires.

All automated. All in one step. Any dev (including the original dev) can now clone the repo, and is one command away from having their dev environment exactly the same as everyone elses. I might clean up my bootstrap and post it here later, but it was mainly pieced together by running the commands over ssh and copypasta back to a shell file.

I think the bottom line here is: AUTOMATE ALL THE THINGS. Since having that set up I've been gradually moving my projects into their own self-contained Vagrant setups when I work on them. It not only makes adding collaborators easier, but where I've got complex build and deploy chains that rely on a lot of external tools, those tools are now just a vagrant up away on any platform, and will always be repeatedly consistent.