Builds And Sanity
The whole tech world is wrapped on the notion we need repeatable builds. There's sound logic to it, but the how has always become contradictory to what are the needs.
In the first of the #StrikingABalance series, I'll discuss over what is the most common ways to do a repeatable build. Then touch a little on what we all could do better, to do more with less.
It is almost a given, but the most common way of doing a repeatable build that should be laid out is none other than an app container. An app container in the following context is one described by the open container initiative (OCI) image-spec. I don't believe I need to explain what they are, with their commonality in the space thanks to Docker and Kubernetes. However, there is one thing I would like to point out in its implementation. With an app container, the way to actually build has stayed using practices of old. Essentially we make snapshots of a chroot environment with a set of bash scripts in the hopes of making our software run how we required it to run. It may sound like its reproducible and it can be, but the trend tends to be far from the goal.
The interesting part of creating an app container image though, is in what you contain for your app container image. It's the tools you add to the container image, which will become the container you run. Ideally, you only add applications that are required to run your software and that's it. But in practice, rarely do individuals take into make an app container, an app container. Instead, trending to garnishing an app container to be no different than that of a system container like LXD. Not to say system containers don't have their place. They very much do and play infinitesimally more important role as we move further into the cloud and abstractions. But a system container, is not what an app container should be.
There's a reason why members of the world are still reluctant to jump on doing everything in app containers. The benefit don't necessarily resolve the problem of making a repeatable and isolated build all the time. In many cases, an app container ends up becoming more complex than that of using the works of package management technologies like DEB and RPMs.
An app container should only run and contain the software you require it to run and that's it. Best case scenario is that you build an app container in a way that the source and its dependencies are the source of truth for the app container. A way to describe the app container's snapshots in a way that are completely identified by the source of the software you are trying to run. There is a trend for this, and it's definitely growing.
In the past couple of years, strides of experimentation have been made to get us to a place where the source is the truth for how an app container is built and what it runs within that container. Two projects that have works doing so are Nix and Habitat. Both projects approach building an app container similarly. In essence, making an app container by assigning an artifact from builds, which are instrumented using a source dependencies for said software. In doing so, an app container's image, holds only the source and libraries required to run the software, while also using extremely advance dependency tree mapping available from a full package manager.
We still have time to grow on creating app container images. if used properly we can have our abstractions for builds to be manageable. So we can focus on what matters, the code we want to run.