End "Works on My Machine" Surprises with Vagrant
This post was originally posted on the Phase2 Blog.
How many times have the following issues happened on a project you've worked on?
- Notices (or worse) appeared on production because of a PHP version mismatch between a developer's machine and the production web servers.
- A new PHP extension or PECL extension had to be installed on production because it was installed in WAMP or MAMP?
- A team member ran into difficult setting up their local environment and spent many hours stuck on something.
- Team members didn't set up SSL or Varnish on their local machines and issues had to be caught on a dev server.
- A team member would like to switch to Homebrew, but can't set aside the many hours to redo their setup until a project is done.
Tools like MAMP, XAMPP, the Aqcuia dev desktop, MacPorts and Homebrew all make it easy to get an *AMP stack up and running on your computer, and tools like MacPorts and Homebrew even make it pretty easy to install tools like Varnish and memcached.
While these tools make it easy to run a very close approximation of the production hosting stack on your local machine (arguably closer if you use Macintosh or Linux,) it will still have some key differences which will ultimately contribute at some point to a "Works on My Machine!" situation in your project.
Luckily, virtualization has advanced to such a degree that there are cross-platform virtualization solutions such as VirtualBox, but just using a VM inside of VirtualBox doesn't solve the whole problem. It makes acquiring the correct versions of software easy, but keeping configuration in sync can still be a challenge for users who are not deeply familiar with Linux.
Enter Vagrant.
Vagrant is a Ruby gem that makes working with Linux virtual machines easy. You distribute a Vagrantfile to your team, and it does the following things for you:
- Downloads and sets up virtual machines from a single .box file which it will download over HTTP or FTP.
- Provisions the software and configuration on the VM using your choice of Chef, Puppet, or simple shell scripts
- Automatically shares the directory with the Vagrantfile (and any subdirectories) to the virtual machine with Virtualbox's built-in file sharing
- Forwards the SSH port (and optionally other ports) to your localhost and avoids collisions so you can always directly SSH to the machine
- Optionally sets up a dedicated host-only IP address that you can use to connect to all services on the VM without port forwarding
- Optionally shares directories to the VM over NFS from a Macintosh or Linux guest, which enables acceptable performance for a Drupal docroot
Since Vagrant handles the file sharing with the VM, you and your team don't have to mess around with setting up FUSE or the like and you can continue to use the tools that you're used to using locally, such as your text editor or garphical source control program.
In addition, so long as you have a single developer skilled in ops who can encapsulate the production configuration into a system like Chef or Puppet, these changes can be pushed down to the whole team. Once your ops team has a working Varnish configuration, for example, they can push that into the Vagrant repository, and then a working Varnish setup on all your developers' VMs is just a git pull
and a vagrant provision
away.
We've been working with Vagrant over the last few months and think it offers a number of advantages. All it takes to get started installing VirtualBox and the vagrant ruby gem. Detailed information on how to get started is available in the excellent Vagrant Quickstart guide.
I've put together a screencast that's just over 10 minutes long and shows the whole process of bringing up a CentOS 5.6 VM with the treehouseagency.com site shared from my local machine.
We'll be posting more example code over the coming weeks that will allow you to try out Drupal from your local machine on a Linux VM.