Tl;dr: Vagrant allows you to create a reproducible development environment that will speed up your development and allow you to collaborate more easily.
Like many other people, I have suffered development pains stemming from small, incremental changes in the development environment and the occasional meltdown. After having settled down to a life of minor misery with Eclipse and Maven (admittedly having moved off Ubuntu because of repeated Java upgrade issues) on OS X, I thought I’d found some level of stability.
Nevertheless, it seems an old dog can be taught new-ish tricks. In our work at Oslo Public Library, we use Vagrant to manage our development environment. Put simply, Vagrant provisions virtual machines based on a description file (the Vagrantfile) that ensures that each time an environment is spun up, it has the same characteristics.
This is great in cases where you’re developing software with other people, because you can share the Vagrantfile with the source and each team member can develop their software in exactly the same environment. It’s also great when you’re working alone, because you understand exactly what requirements your software has — many times, you’re working on quite “dirty” systems that have been fixed and bodged making it simple to overlook things that will cause issues in testing. You also find that the you can do a lot of messy trial-and-error stuff without breaking your development environment since you simply spin the environment up afresh when you’ve found what you need to know.
There is a catch of course, you’re running this stuff in a virtual machine, which may not be familiar — we still have a lot of bare metal development environments, but this is surely fading out. The way that Vagrant interacts with the local system can also cause issues — in its simplest form, you simply put the shared resources — typically source code — in the same directory with the Vagrantfile, it works well. I have had issues arise when the environment has a complex setup utilising Docker images, where I met with issues keeping the various linkages in sync. I also met issues when I was trying to be clever with port forwarding to the host.
These latter issues are largely avoidable by not trying to be clever; it’s fully possible — and probably desirable — to create simpler setups and use X11 forwarding to access instances of software running inside the virtual machine rather than forwarding ports here and there and linking containers within containers to access files on the host.
If you want to take a look at a simple project that demonstrates a few of the concepts, take a look at fuseki-docker.