Using Vagrant and VirtualBox as a Dev Environment

published on Sept. 25, 2011, 7:24 a.m.

I do software development on a MacBook Pro. Generally it provides a great system that supports most unix software and makes it easy to install everything from Postgres to Memcached.

I also deploy just about everything to Linux, usually Ubuntu 10.04 LTS.

Here's a problem I ran into with a recent deployment of a python project:

AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'

OS X Lion ships with Python 2.7, Ubuntu 10.04 is at 2.6.5. The total_seconds method, while useful, is new in Python 2.7. So what's the solution to preventing these surprises?

Develop in the same environment as you deploy to.

I suspect very few developers run Linux on their computer, much less the same distribution that is on their production servers. The solution here is to run a VM as your dev environment, setup identical to production. This is where Vagrant and VirtualBox come into play.

Vagrant provides a very good getting started guide, and shows how to get vagrant installed and running on your machine.

Here's a very simple config that gets you a 64-bit Ubuntu 10.04 LTS VM.

Vagrant::Config.run do |config|
config.vm.box = "lucid64"
config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
config.vm.network "33.33.33.10"
config.vm.forward_port "http", 8000, 8001
config.vm.share_folder "project", "/my_project", "."
end

When running a web app on port 8000 on the VM you can open up a browser and load it at:

http://localhost:8001/

So what does my workflow look like now for doing software development? I open up a terminal window and type:

cd path/to/my/project
vagrant up
vagrant ssh
cd /my_project

From here you can start the development server for your web app normally. If this were a Django project you'd type:

python manage.py runserver 0.0.0.0:8000

You can also leave all the processes running on your VM, and use 'vagrant suspend' to stop the VM, and 'vagrant resume' to start it, with everything as you left it. This is extremely helpful when you run a full development stack with several running processes.

In a future post I'll go over how to use Vagrant's built-in puppet support to make it easy to automate package setup and deployment.