10/10/2022
Chainguard recently announced Wolfi, a set of container images that are built directly from Alpine packages and not Dockerfiles.
Ever since Docker released in 2013, we have been using Dockerfiles to build containers. They work well, but there are some problems:
Let's look at the solutions provided by Chainguard that try to address these (and more) problems.
Melange is a builder for Alpine packages. It uses pipelines similar to common CI/CD services, and it builds for multiple architectures by default. Here is a simplified example of a package build for the forum software NodeBB:
package:
name: nodebb
version: 2.5.3
dependencies:
runtime:
- nodejs
environment:
contents:
packages:
- alpine-baselayout
- ca-certificates-bundle
- nodejs
- npm
- git
pipeline:
- uses: fetch
with:
uri: https://github.com/NodeBB/NodeBB/archive/refs/tags/v${{package.version}}.tar.gz
expected-sha256: 92e390d7cda190e7f098833cbbbf03fbe1c50f25653656ad589ae97dc18a7684
strip-components: 0
- runs: |
mkdir -p "${{targets.destdir}}/usr/share/nodebb"
cd NodeBB-${{package.version}}
cp install/package.json .
npm install --omit=dev
cp -a ./. "${{targets.destdir}}/usr/share/nodebb"
Under the environment section, we set up a build environment. Then we call the built-in fetch pipeline to fetch the source code bundle, verify the hash and extract it. There are a few more built-in pipelines, but we can also write our own.
Next, we run a short script to install dependencies, run a build and copy the resulting files into a destination
directory. Everything under targets.destdir
is copied into the package, which will only depend on nodejs, as we do not
need npm or git at runtime.
Now, we can use melange to build an apk package. This isn't a container yet, but for that, we use the next tool.
apko takes apk packages and builds them into OCI images (aka Docker images). Sounds quite simple, because it is:
contents:
repositories:
- https://dl-cdn.alpinelinux.org/alpine/edge/main
packages:
- alpine-baselayout
- nodebb
entrypoint:
command: /usr/share/nodebb/nodebb start
Note that there is no base image being used, instead, we get exactly what's in the packages we list. alpine-baselayout
adds busybox and the standard directory structure.
We can include other apko definitions as a base or create users and groups and set up file system permissions, but that's about it. apko lacks most capabilities of traditional OCI image builders as it's meant to be combined with melange, adding a files and folders directly is not supported. But what it does have is native support for s6 in case we want to run multiple services.
apko is quite fast, all it does is extract apk packages into OCI images and it doesn't run scripts. This is what enables fast rebuilds of images after an individual package is updated, and also makes them reproducible.
Using both tools, did we solve the problems we laid out before? Let's see.
We already use apko to create images for our own use (planned public release at a later stage). The technology works well, but we have questions. The state of glibc support isn't clear to us, and documentation is bare-bones. And while melange and apko are technically faster than Dockerfiles because they can be more selective about what needs to be rebuilt, there isn't tooling that takes advantage of that yet.
There are always the Wolfi images to use as base images in standard Dockerfiles. For the story behind the creation of Wolfi, this insightful Twitter thread by Ariadne Conill is worth a read.