Build docker images better ? Ft. docker build(x), buildkit !

ยท

3 min read

Table of contents

Docker has proven to be a go-to candidate for packaging and deploying applications. While the normal docker build command seems like magic on its own, here are some common pitfalls that you should be aware of.

  1. It does not clean up intermediary images that are created as a part of the build process.

    Eg. Intermediary stages in a Multi-stage build

  2. It does not support concurrent execution in multi-stage builds

    Eg. You have steps in a multi-stage build that do not depend on each other, so concurrent building should be an option, right?

  3. This is probably the most annoying part, It does not provide an option to build images that are compatible with multiple platforms/architectures.

    Eg. Common problem on M1 macbooks -> Build the image on your M1 mac machine and see it bark exec format error on a cloud environment or a friend's Windows or Linux PC (one that has a non arm architecture)

Now, let's enter the realm where amazing tools โœจ like docker buildx and buildkit exist!

BuildKit

If you have not heard of this before, this project from moby is an absolute bargain ๐Ÿ˜ฎ. TLDR; It decouples the docker frontend (which would be a set of instructions to build a docker image. Eg. A Dockerfile) from the backend (the logic or strategy used to build the image).

It was maintained as a separate project but was later integrated into the docker engine. You can enable BuildKit features by doing this export DOCKER_BUILDKIT=1 on your terminal.

Here's a quick demo of the useful features that BuildKit provides. There is much more to buildkit. Visit the project's repo to explore features in greater depth.

Well, It solves the first two issues mentioned above, in fact very well ! But if you are wondering "what on god's green Earth ?" is going to solve the other issue, take a peek into the next section

docker buildx

Docker CLI plugin for extended build capabilities with BuildKit

Well, It might seem to be just a CLI plugin. Believe me, it is a lifesaver in a developer's workflow when it comes to building images that are compliant with multiple platforms. The detailed documentation of how to build images using buildx can be viewed here. This is not a tutorial to demonstrate all features buildx provides.

On an overview, if you are a developer working on an ARM machine trying to build an image compatible with AMD platforms or vice versa, you would do this

docker buildx build -t <my-cool-image-name> --platform=linux/amd64 .

This command would build an image that will be visible when running docker images. Seems normal right ? But, that's not it. The image you built now is completely compatible with the platform you specified eventhough you might be building from a totally different environment. Cool right? ๐Ÿ˜

Although this might seem cool, here are some heads-ups that can be useful if you are trying to build for multiple platforms by using the same command,

  1. You should have multiple builders enabled. Do this using docker buildx create --use --name=<builder-name>. This is what BuildKit will eventually use to concurrently build multiplatform images

  2. when you specify multiple platforms in the buildx command (--platform=linux/amd64,linux/arm64) and see the list of images, you will not be able to see your image on the list. You should either export it as tar, push it to a docker registry by including --push flag, or run separate buildx commands for each platform.

Now you are all set, to build docker images in a better way using buildkit and docker buildx.

If you have read the blog all the way until here, please consider posting feedback by DMing me on Twitter since this is my first ever blog !

ย