What I’ve Learned

Why Every Open Source Project Needs a Development Container?

What I’ve learned from building a dev container for an open source project

Stefan Nastic

--

The Pillars of Creation in the Eagle Nebula by Hubble Space Telescope

With the rise of cloud native applications and the advent of microservice architectures, a lot has changed in terms of how we develop applications. Recently, I have spent some time setting up development containers for Polaris SLO Cloud, an open source project I lead. My main aim was to make our project more accessible to our (future) developers. Since it is a Kubernetes project, configuring local development environment can be a project in itself — I wanted to improve this experience.

Development containers

A development container is a running Docker container with a well-defined tool/runtime stack and its prerequisites¹. Basically, a development container should automate everything that needs to be done before being able to start writing the code and run it locally.

This notion of having all necessary development tools packaged and distributed in a container has been around for some time. Recent introduction of Remote Containers (VS Code extension) and Dev Environments (a Docker Desktop feature available since v3.3.1) has made building, shipping and using dev containers much easier.

Development lifecycle

Ideal development workflow probably looks something like this: you open your favorite IDE (locally or remotely), checkout a git repo/branch and start writing code. To run the code, you simply click Run/Debug project.

This workflow is very familiar, as we eventually achieve it for most of the projects — usually only after investing a lot of time installing, setting up and configuring our development environment, potentially having to document every step — Development containers try to enable such workflow from the first git clone. This in turn can improve team communication, project maintainability and developer satisfaction (this is a real thing²).

Benefits of development containers

Development containers can be beneficial to all sorts of projects, not only open source projects. I would argue that if a project has a team of developers (>1 person) working on it, it probably makes sense investing time to set up development containers. Let’s have a look at some benefits of shipping a development container with the code:

  • It allows developers to quickly access and take the code for a test ride. This one was particularly important to me, as we are trying to bootstrap developers community around our project. Nobody has time nor wants to spend hours or days just to be able to run a simple HelloWorld example…
  • It minimizes the impact of third-party changes to the dev tools and runtime stack one is using. I think, this one is universally true for any project, but it particularly affects larger teams, which use a lot of open source tooling. This boils down to minimizing own responsibilities and maintenance scope. For example, we want to minimize time spent updating our documentation due to changes in third-party dependencies.
  • It can enforce security best practices throughout organization or community. Recently, this is becoming increasingly important for the local/remote dev machines, due to increasing popularity of supply chain attacks³ ⁴ which exploit the weakest link of software delivery lifecycle.
  • It simplifies experimenting and learning. Changing the development context can be very tricky at times and dev containers can simplify it. For example, with dev containers it is possible to easily switch between different git branches, without having to spend time restoring configurations, environment and runtime services.

Other considerations and caveats

Development containers are still rather immature and there are some drawbacks to working with them at the moment:

  • Still rough around the edges. Although, containers are a fairly mature technology, dev containers still leg behind, particularly in terms of tooling support. This makes building custom dev containers still a little challenging. I think the main reason is that dev container are human-centric, i.e. meant to “host and orchestrate” human tasks. This is simply not how we typically use containers these days and better tooling support is needed.
  • It can be painstakingly slow. Currently, there is a rather tall software stack and a large number of virtualization layers that underpin the dev containers. The performance naturally depend on the nature of one’s workstation (resources, virtualization support, OS, etc.), but even the most routine tasks can be very slow. For example, if you mount a source code directory from host into a container (without using a volume), executing simple build/install and run can take a looong time.
  • Managing portable configurations. When trying to put things in containers, having to write custom shell scripts seems inevitable. Dev containers don’t seem to be any different. What I found the most annoying was having to manually mount and parse host’s config files (e.g., Minikube), so that they make sense when applied inside a container. For example, replacing localhost with host.docker.internal with sed.

Closing thoughts

I believe that development containers have potential to soon become de facto standard in most modern projects. Moreover, it wouldn’t be surprising if they quickly establish themselves as an integral part of the mainstream DevOps. This could also generate various (business) opportunities in terms of offering specialized tooling around the dev containers.

Another thing, which I find appealing is the idea of commoditizing development workspace. Dev containers could be a catalyst here by enabling to quickly spin up fully configured, remote dev environment in the Cloud (also with necessary IDE extensions, plugins, customizations, etc.).

In the future, I am planning to follow up with a tutorial on how to set up a development containers using VS Code, i.e., how I did it for our open source project. Also I would like to explore some other similar ideas and tools that can facilitate optimizing for developer satisfaction as opposed to optimizing for busy work.

Update: How to tutorial is now available.

If you would like to find out more about our Polaris SLO Cloud project, check out our GitHub or follow me for updates.

--

--

Stefan Nastic

Software engineer, Cloud expert, DevOps enthusiast. Sharing my experiences and learnings from solving interesting engineering problems.