Original article posted here.
A developer's environment is akin to a workshop, a control room, and a kitchen but within the confines of a magical whirring box. Unlike these tangible things, however, a development environment is not as static: at the end of the day the workstation is powered down. The next day, instead of your work, tools, and experiments remaining as you left them, they are packed away and require a tedious setup. Why is this? Instead, could you operate without having to setup your environment at the beginning of every work day?
For certain types of development, it is certainly possible to avoid this tedium. The secret is to work in a virtualized development environment.
At the time of writing, my development VM has been up for 109 days, 9 hours, and 42 minutes. In the past 109 days I've done a lot to my host machine: changed Linux distros twice, performed a bunch of kernel upgrades, and done countless reboots (and suspends/resumes). During that time I've only set up my development environment once. Each morning begins with me turning on my computer, making coffee, and SSHing into my development VM.
Not only is my development VM convenient, it's also running under near-identical conditions as the production app-server environment: same OS, memory characteristics, CPU topology, third-party software versions, library versions... It's as close as I can get without developing in my production environment. A great deal of configuration headache and/or guesswork is eliminated as a result. Further, keeping my development environment distinct from my bare-metal OS frees me from constantly running a bunch of daemons and other cruft.
Here's the beginning of my work day:
- ssh into VM
- reattach screen session
- <do work>
Let's say I start working on a new project. No problem:
- create a new VM
- git init
- and I'm off
Now what if I add a new developer?
- clone VM
- change VM username/passwords/etc
- slap the VM files on dropbox
- more coffee
If the first step in factoring your development out of your bare-metal OS is moving to a VM, the second step is hosting that VM on a distinct machine altogether. I use a spare machine as a file server. It's loaded with RAID'd hard drives and most of the time it's not doing anything. Well, it was never doing anything until I decided to use it as my personal cloud.
With my VMs being hosted on a machine that is always on, I don't even need to pause/save my VMs at the end of the day. All I do is close a few terminal windows and suspend my bare-metal machine. The next day I just resume my machine and ssh in to my VM and I'm already at work.
One day when I was fiddling with my router I forwarded a high-numbered port to point at ssh on one of my VMs. Now I can work on the project that lives on that VM from anywhere in the world that has an internet connection.
It's not all roses. None of what I've outline is all that practical if you're not used to working exclusively in a terminal. As I spend most waking hours with my beloved Vim, this suits me wonderfully. When I have to use Eclipse this VM magic isn't an option for me.
I imagine not everyone is free to install whatever the hell they want on their workstations. Obviously this solution isn't going to work if your boss is The Man.
Clearly there are application domains that just aren't well suited for virtualized development. Number crunching and doing cool graphicsy stuff come to mind. If you're a lowly back-end developer you may be in luck, though.
My day is made easier and my life simpler by developing in a VM. Virtualized development isn't going to work for everyone, nor will it please everyone. Consider it another tool in your chest.