It's crucial to make sure everyone's local environment is identical if you're a part of geographically distributed team and your project is composed of many services. It's also quite unlikely that all cogs in your app will spin self-sufficiently. Search engines, various APIs, authentication endpoints and HTTP accelerators - all of these services are standard these days. Your app is a part of a much wider picture.
This complexity forces you not only to broaden your mind during design phase, but it also affects the way your software is deployed. All the moving parts should be available on every single environment - including the one that works on your machine. Having in mind aforementioned complexity double click on a ZIP file is a poor man's solution. Duct taping things will end badly. And if anything can go wrong, it will, so better be prepared.
Our goal was clear - portable, versionable and predictable environment everyone can run. Throughout our journey with Vagrant, Packer and Chef we learned a lot of things:
• how box over-optimization can lead to poor user experience
• why it's important to make first "vagrant up" as quick as possible
• not everything should be dockerized
• Vagrant box is a 'virtual' release artifact and needs the same care your app receives
• successful Packer build is often half of the story
• why Consul deployment in a Vagrant box is not as trivial as it may sound
• how to optimize long Chef runs and provide more granular approach to your dev team
• it's surprisingly easy to get from "I don't want to run any VMs on my laptop!" to "Hope you have Vagrant for that".