Sunday, March 9th, 2014
When I first started in web development, I would manually install the required software (Apache, MySQL, and PHP most often) to my local machine. For years I had been setting up a new development environment every time I changed operating systems or bought a new computer. This is always a hassle, and can lead to inconsistencies if some configuration is not the same in a new install.
In 2011, I moved my development environment to a virtual machine using VirtualBox. By setting up the development server in a VM, you can use an operating system and software packages as close as possible to the development server which it will be deployed on. This will help prevent bugs arising from the configuration difference between development and production. It is also nice to be able to shut down the development environment entirely when using my laptop for personal activities.
After working with a development environment in VirtualBox for a number of years, I recently found a software package called Vagrant. With Vagrant, the development environment is defined in code, and can be stored alongside the project code. The provisioning itself is handled by a puppet, which automates the software package installation and setup. It is easy to see at a quick glance what configuration changes you have made, and keeps everything in one spot.
I have created a sample project which provisions a basic LAMP server using my Vagrant Debian Wheezy box as a base. You can see the Vagrantfile simply defines the box to use, a few ports to forward, and the location of the puppet manifest to provide the provisioning information (which is the puppet directory.) Finally, the www directory will be the default web root folder for apache.
After installing VirtualBox and Vagrant, just checkout the project and run the command
vagrant up to start the provisioning process. The first run will take a while, as the 507MB base box has to be downloaded, but subsequent runs should be quicker.
Once it is up and running, open your web browser to localhost port 8080, and you will see the contents of the www directory served. You can make changes in that folder, and they are automatically shared with the vm, just like developing natively.
When you are done, run the command
vagrant halt to shut down the VM. Issuing
vagrant up again will boot the VM back up. You can optionally run the command
vagrant destroy to delete the VM and free up some hard drive space. It will be recreated when issuing a
vagrant up command from that state.
If you look through the modules in my puppet provisioning script, you may notice it is setting up a postfix service. This service is setup to capture and redirect all outgoing mail to the vagrant user. This should prevent any unintended messages from leaving the dev environment. You can then run the command
vagrant ssh to open an ssh shell to the VM, and read the messages by running the
The only downside I've noticed so far is that the VM is unable to bind directly to any ports below 1024 as it is not run as root. This is why apache is set up to use port 8080. A workaround I've found is to run the following command from the host machine, which redirects port 80 to 8080.
sudo socat TCP-LISTEN:80,fork TCP:localhost:8080