It works on my system
If you're a web developer you've almost certainly been in this situation; you get a call for a bug in production or for something failing in an automated test that works/passes in yours. You spend a few (or more) hours to finally find out that someone, sometime changed a single config option on the server or that a recent update in your computer changed a version of something that now causes different responses between your system and the production server. While you might be tempted to respond ‘it works on my system’ and try to walk out, we all know that can't really be a solution :)
Expecting to maintain exactly the same versions of everything between a production server and your local machine is probably naive. It won't be long before things diverge. That could happen completely unnoticed, or it might be a conscious decision when there simply isn't any other option. And that doesn't even take into account the need to work on different projects with completely different requirements. Package managers (i.e. pip, composer, npm) will help, but they limit themselves to language specific packages. No tool can rule them all!
Virtualization to the rescue
Virtualization (the ability to run a system within a host system) has really helped with this problem. You love your Windows desktop but develop for a Linux server? Want to test run a Hadoop setup on your Mac? Have a client with an SQL Server but develop on Linux? No problem. As long as memory and CPU cycles allow, the virtualized platform won't have a clue of what's going on. You can even deploy the virtualized box on a real server and have it working exactly as it was inside your computer. While this is a huge step forward, there are still issues to deal with. Files stay inside the box and if you mess up with some configuration it's really expensive to go back to where you started (if you remembered to take snapshots!). Add to this that backing up becomes a major issue after a while, and syncing changes with others is next to impossible. Docker sorts out some of these issues, making changes easier. But while being really promising it answers a different question.
You vagrant, you
Enter Vagrant. The naming might not make sense even after reading the product description "Create and configure lightweight, reproducible, and portable development environments". Vagrant allows you to set up a development system following instructions on a simple text file. It is so lightweight that servers can be created and destroyed so easily that they come and go as a, well you guessed it, vagrant.
Vagrant used to only work with virtualbox (a free virtualizing platform from Oracle) but nowadays offers other providers too, including support of Amazon's EC2. If you're using Amazon's infrastructure for your production that's really helpful. It also now includes support for most system scripting tools the ‘dev ops’ people like to use like chef, puppet and more. I'm more of a bash guy so I don't really care about these for the simple things I do, but our sys admin is happy to be able to use the same scripts for both starting production servers and local vagrant machines for development. And having a happy sys admin makes everyone happy as well :)
The time that you had to post instructions with the exact commands to install necessary system dependencies and debug issues between systems is long gone. You just add the Vagrantfile to your project with the setup script and all people need to do is vagrant up
. You messed up the system? No harm done, vagrant destroy
will only take a few seconds to get you back where you started, without any change in your system! Decided to spawn the server again? Just vagrant up
, and a few seconds later a fresh like new server will be up (well it is not ‘like’ new, it is new!).
The nice thing with vagrant is that, by default, it shares the folder where Vagrantfile
lies on the inside of the virtualized system, in folder /vagrant
(you can add more shared folders and change the internal paths). So, all the project files can stay outside the box and destroying it won't do them any harm. Working on your computer means everything is fast since it is local, but the actual code runs inside the vagrant box so you don't have surprises. If you're using apache inside the vagrant box, you might eventually run into permission issues when the apache process is unable to write on the /vagrant
folder. The thing that works for me every time is to simply change the apache user from www-data
to vagrant
inside /etc/apache2/envvars
. Permission issues gone!
Sharing changes in the server environment is as easy as checking out the new Vagrantfile
from the repo (we do hope you use some version control!) and re-provision or destroy/up a server.
If you're not using vagrant already, give it a try!