Reproducible developer environments

Mihai Gramada
4 min readAug 20, 2016

--

There’s a certain bond between a developer and his development environment. People spend large amounts of time getting their setup just right. However, things can go wrong. Hardware failures, misconfigurations, a system that has grown over time into this unmaintainable mess of packages, dependencies and tools from multiple languages all bundled up into a single machine, which eventually fails.. ¯\_(ツ)_/¯

Will Farrington from Github has an awesome talk about how they tackle this. You should go watch it. Please. Do It Now!

Watch Will Farrington’s talk

Started learning go recently, so I went through the process of setting up a dev environment for it. I love vim, so I set up a nice little environment with autocompletion and some other integrated tooling. Since the setup process was not trivial, I tried to make it reproducible so that I don’t go through the same pains again.

Ok so before we start, this is not going to be the UltimateSetupGuide. It’s basically something I hacked together in a couple of hours to show how it can be done. I just use vagrant for VM management and some shell scripts for provisioning, and i’ll mention some ways to improve on this later on.

Strap in, we’re going to go for a ride. Ok, so i’ll show you the steps that I have to do now to get another go environment with the things I like . Ready? OK HERE WE GO!

  1. git clone https://github.com/grameh/GoDevEnvironment
  2. cd GoDevEnvironment && vagrant up

go get” a coffee ( ͡° ͜ʖ ͡°)

There. That’s it. The “basic example” that is included is a CRUD api that uses a local sqlite database. Simple stuff. The vagrant configuration that is included also creates a private network between your machine and the VM, so if you run the binary, you can make requests to 192.168.33.10:8080 from your main machine. It can serve a glorious static file, or accepts requests to the CRUD api. Incredible, I know..

I can now basically start dev’ing around. The packages that I need are on that machine and as the project i’m working on advances, if keep the vagrant provisioning script up to date I can be sure that I can lose my laptop and continue working without a hitch. You might argue “Hey, why would I ever want to have one vm per project i’m working on ?”.

Why do it for your dev box? Manual configuration. It’s a crime

ಠ_ಠ.Unless you’re working on 10+ large projects SIMULTANEOUSLY, I think you’d be ok. Plus, you don’t have to keep all the VMs. As long as you kept your provisioning up to date, you can just “vagrant destroy” whatever you’re not working on at that moment to save up space.

Storage is cheap, but your dev time isn’t. You don’t really want to lose days
setting up your machine and being unproductive until you get it back to the desired state. If your workplace does it, onboarding a new team member becomes a breeze, and you can focus on bringing him up to speed on the business logic side, instead of wasting time and energy on environment setup.

The setup i’ve provided is REALLY simplistic. It’s basically using just a couple of bash scripts for provisioning. One of them (aptly called setup_system.sh) runs with elevated privileges (checks them too) and basically installs a bunch of packages from apt.

The other, (setup_project.sh) does a bunch of configuration that doesn’t need root permissions (such as configuring vim for me, setting up some environment variables, getting the project’s dependencies).

Ideally, you should make your provisioning idempotent, so that whenever you need to bring in a new dependency you just run vagrant provision again, instead of installing it on the VM. There are tools such as puppet or chef that can really help out with this, and they can be used with vagrant.

TL;DR

  1. Try to separate your environments for different projects. Using VMs is a great way to do this and vagrant is a great way to manage them.
  2. You can provision your VM’s environment easily, just by some scripts
  3. If you do this, you make it repeatable, eliminating your dependency on your main dev machine.
  4. There are tools out there to help out, such as puppet or chef (the latter supports Windows as well), that can make your provisioning more robust, and also platform independent.

Try it out and let me know what you think.

Disclaimer: Opinions expressed are solely my own and do not express the views or opinions of my employer.

--

--