Development environments done right, with Vagrant, Puppet and VirtualBox

vagrant_structure

When I first started out in web development, I worked directly on the server. I had an FTP client and I’d download files, edit them, and re-upload them. If it was a “serious” project, I might even use source control. I thought this was a pretty handy way to work… Looking back on that workflow, I’m embarrassed, but the thing is, I know people who still work that way. I’m not going to go into the merits of having a dedicated development environment, automated builds and tests, etc… Just take it as a given that you need them. With that being said, however, it’s always a pain trying to set up a new development environment, and having an environment already set up on my laptop doesn’t guarantee that it’ll be the same environment that the next client has in production. If you’re on a different machine, it’s a problem. I’m going to talk about how I’ve solved this age old problem using Vagrant, Puppet and VirtualBox.

VirtualBox is an open source Oracle product that allows you to run virtual servers. I’m not going to go into the deep secrets of virtualization, but in a nutshell, a virtual machine is an operating system that runs inside a software defined environment. So, on my laptop which runs Linux Mint, I can run a headless Ubuntu server inside VirtualBox. Very cool stuff.

Vagrant is essentially a “wrapper” around various virtualization systems. It supports VirtualBox, VMWare, AWS, and supposedly “any other provider” of virtual environments. From my experience, it tends to favor VirtualBox, and I haven’t actually tried it with and others, so YMMV. For the remainder of this post, I’m going to assume that we’re using VirtualBox. Basically, it provides a consistent method of provisioning and managing VM’s, so you don’t have to worry about interfacing with VirtualBox. All you have to do is set up some basic configuration, then you can start a new instance of your VM with the command:

vagrant up

Finally, Vagrant works with “industry standard” provisioning tools such as shell scripts, Chef, Puppet, etc… in order to provision and configure the virtual machines themselves. I’m using Puppet, since that’s what I’m most familiar with.  Puppet is “IT Automation” software that allows you to configure your environment in an automated way. It can install packages for you, populate configuration templates, deploy applications, etc… Basically, it configures the packages, files, and applications that wind up installed on your VM.

What I’m going to do is use Vagrant to configure and spin up a complete development environment on VirtualBox. Puppet is going to run and ensure that Apache, PHP, MySQL etc… is installed and ready to roll. I’ve copied other people’s work egregiously with this post, and I based most of my configuration on Patrick Lee’s excellent examples at https://github.com/patrickdlee/vagrant-examples. Standing on the shoulders of giants and all that… In any case, at the end of this little ramble session, what you’ll have is a VM that’s actually running two Ubuntu 12.04 servers. One will be loaded with Apache and PHP, and the second one will be a standalone MySQL server. I’ve been working on a series of posts about the Kohana PHP framework (see this, and this) and I’m using that code as the actual web application that is running on these servers.  On my machine, the “site” directory is the base of my Kohana application, but in the repo that I’ve shared on GitHub, it just contains a .sql file that Puppet uses to populate the database.

First, download and install VirtualBox and vagrant.  I’ll leave the installations to you, as they’re fairly straight forward, and there’s good documentation for both.  Then download my repo from GitHub  into a new directory.  Inside the new directory, the “puppet” directory is where I’ve defined all the things that puppet needs to deploy and install. The other directory, “site”, is kind of special. Vagrant sets up a shared directory somewhere between the virtual machine, and your host machine. So, once we get the VM’s up and running, I can continue to make changes to my code on my local machine inside that shared directory and they’ll immediately be available on the VM. That’s actually one of the downsides to virtualization. Changes that you make on the VM don’t persist between sessions. So, if you make changes to your bashrc, or /etc/hosts on the VM, then kill it, those changes won’t be there the next time you start the VM. In any case, “site” is a completely arbitrary name.

So, once you have your vagrant and VirtualBox installed, and you’ve copied my files into a new directory, you can just go into that directory , run the command

vagrant up

Wait a few minutes while the magic happens, and you’ll have an awesome VM running two separate servers. Still inside that directory, run

vagrant ssh ex6web

to ssh into the web server, or

vagrant ssh ex6db

to ssh into the DB server. From there, you’re on your own, but you now have a development environment that you can take with you wherever you go.