News Archive
PhpRiot Newsletter
Your Email Address:

More information

Facilitating Development Environment Consistency

Note: This article was originally published at Planet PHP on 24 December 2011.
Planet PHP

Every developer is different, but your team's development environment does not have to be. A modern web app uses many different technologies. Common dependencies for a functioning web development environment include PHP and its necessary extensions, a web server, a database, testing frameworks, and other apps and services. The classic approach to assist a team of developers is to deploy a server and install all of the necessary packages one would need for development. This methodology provides a consistent environment for all of the developers on the team, therefore ensuring that all contributors receive the same experience throughout the development cycle. However, as consistent as a remote, homogeneous development might be, developing remotely introduces a number of problems, including speed sacrifices, and a nasty dependency on a reliable connection to the Internet. It is also difficult to tinker with experimental packages when you know it could affect the environment of everyone on your team.

Navigating a remote file system in order to find the file you want to edit can be cumbersome. Many text editors and IDEs have features that attempt to mitigate this pain, but I have never found one that works reliably and is comparable to the speed of local development. Saving a file over a network can introduce delay that adds up to a significant amount of lost productivity over time. File navigation aside, nothing beats the speed of working locally. In order to work on your local machine, you have to install all of the packages that the team is using, and each member has to do so as well. This approach introduces inconsistency. As developers, we seek consistency, speed, and, as much as we love the Internet, we would like to be able to work without it sometimes. So, what do we do? We build a machine within a machine that works on all platforms and ensures homogeneity across development environments.

Thanks to advances in virtualization technology and the open source community, a number of free tools exist that one can leverage to facilitate providing consistent virtual machines to your team.

VirtualBox, Vagrant, and Puppet

There are a few apps that are required in order to get started. VirtualBox is hardware virtualization software that allows you to run another operating system on your local machine. Vagrant is a set of scripts that allow you to easily manipulate those virtual machines from the command line. Puppet allows you to define what configuration changes should be made to the machine to have it operate how you would like.

Install VirtualBox

Download and install VirtualBox. You are now ready to install any operating system and run it locally.

Install Vagrant

Vagrant is a command line tool for building and distributing virtualized development environments with VirtualBox. Executing only a couple of commands, you can download and provision a virtual machine which matches that of your team.

Ruby and its package manager RubyGems are required to get going with Vagrant. There are detailed instructions by platform to help.

Once Ruby and RubyGems are installed, execute the following command on your local machine to ensure that your packages are up-to-date.

gem update --system

To install Vagrant, issue the following command on your local machine:

gem install vagrant

Configure Vagrant

Assuming that everything has gone well, configuring Vagrant should be easy. I have created a sample Vagrantfile and base Puppet configuration in order to provision a machine with Apache, MySQL, PHP, MySQL, Xdebug, PEAR, PHP CodeSniffer, and PHPUnit. You can clone my repository.

Once you have cloned the sample repository, it is time to install the Vagrant base image. The following command will download the box via the Internet and cache it. It is a 300 MB download, but you should only have to do it once.

vagrant box add base

The next step is to modify your Vagrantfile. Its configuration will forward ports from your local machine to the VM, mount a local folder of your choice within your VM, and initialize Puppet as your default provisioner. I have already done this for you.

There are a couple important configuration directives in the Vagrantfile. Let's take a look.

# This enables Puppet as the default provisioner config.vm.provision :puppet # For verbose output, and you wish to do a dry run, substitute this line config.vm.provision :puppet, :options = "--verbose --debug"

Truncated by Planet PHP, read more at the original (another 5717 bytes)