Much of the software we develop is made some platform in mind. It might be mobile phone, embedded system, something proprietary. Nowadays however, we do much of application development on top of web stack which consists of a back-end server and an html front-end coupled together with a variety of other components.
When it comes to development environments in such projects, I’ve seen many and been repulsed by many. For some reason, often development infrastructures are not built for developers or ops personnel. Rather they are some odd mixture of corporate politics, odd policies and legacy mindset. This is usually conflicting with my need for a customizable, portable and disposable development environment.
That said, whatever your stack is, I bet the idea of it travelling with you sounds good. You really want a local development environment.
Isolation is the key
Most of us work with a laptop of some kind and it’s not uncommon to just install a LAMP stack straight from the package management system of the OS of your choice. You can run multiple instances of Wordpress with shared databases or multiple JavaEE application servers if you wish. If you have good amount of discipline, you will remember to get rid of the systems you don’t need. You might even keep environments like Node.js in good order under your home directory rather than install them system wide (though NVM helps greatly on this one). I personally lack that discipline.
I found rather early that pollution caused by different environments on a same machine just plainly sucks. Testing things with different run configurations tends to get hard over time. For example, reverting to base configuration and testing repeatedly with one changing attribute starts to be nerve wrecking.
It’s not even guaranteed that you can run the environment in your laptop. Many companies have “harmonized” test environments to be run on remote computers. I’ve encountered standalone test servers, mainframes where you code, compile and test your binaries remotely, rsynced local directories to remote environments… Usually these practises are a legacy born ages ago, and it’s expected for developers to fit into the development system, rather than to continuously improve the system to fit the needs of developers. Oh, and needless to say, even the best VPN usually doesn’t work when you have to test that hot-fix from home so you can get to sleep.
I’m not having it
These days I mostly don’t have it this way. Generally our computers pack the punch to run multiple virtualized environments concurrently, so simulating complex stacks isn’t much of a problem itself. On the other hand, managing them might be.
The tricks I will show are done in a Linux environment. Most likely they are transferable to BSD environments pretty much as is. On Windows, there are virtualization solutions with variable overhead, on OSX you might be interested in chroot jails or run a virtualized Linux based OS, but neither of these solutions will offer the speed and same isolation possibilities as container based solutions.
On a personal note, I’ve never understood the popularity of the OSX operating system as a platform for any other kind of development other than for the Apple ecosystem. Fortunately, if you want to test container virtualization in OSX, you can easily run your preferred flavour of Linux in a virtualized environment.
And neither should you
So what you really want, is a local development environment. Something you can create when you need one, and discard when you don’t. Preferably something you can parameterize easily and which can be isolated with as little overhead as possible so you can run multiple sandboxes.
For this specific thing I’ve used tools like Vagrant, Docker, Puppet, Chef… and some others, but let me introduce you to some very basic tools that I currently find overly awesome because of their apparent simplicity and focus: Ansible and LXC Containers.
Usage of configuration management tools like Ansible and the likes has been exploding especially now that DevOps has become a thing. It’s super. Not only do you have the power to rapidly replicate the configurations of you environments to virtually any node (virtual or metal, local or remote), but you also have a human readable configuration of your running platforms.
Ansible shines in readability. Use of YAML and declarative resource patterns makes configurations generally very easy to comprehend. For such tools, I think this is as least as important as is the pure efficiency or speed. Or even compactness of the description language.
LXC on the other hand is a superior way to to create isolated environments. Container based virtualization is cheap and fast. LXC is very easy to use (you will really be surprised) and by creating a “base” setup and cloning it for different needs, you can really speed up testing of different scenarios. Even if you would configure instances manually.
But when combining the power of these two, things get really exciting, and at least as we have witnessed, very efficient and fun!
In next articles in this series, we’ll examine Ansible, LXC and their combined usage in detailed level.
Meanwhile, go on and experiment yourself.