BuildKit Features You Might Want to Know About
Accessing private Git repositories during a Docker build, handling secrets and re-downloading lots of dependencies.
If you have struggled with these topics, BuildKit could help you solve them in a more elegant fashion.
I’d like to introduce some of those new features to you, and give a quick impression how they can be used to improve your existing workflows. If you want to see all of them in the docs, check out this docs file from BuildKit’s GitHub repo.
How to BuildKit
BuildKit was shipped with the Docker Engine since 18.06.
It’s an alternative build engine, built to be more performant than the default build engine. It provides some new features as well.
To use BuildKit, you have to enable it. This can be done by setting an environment variable:
Alternatively, you could build your images using
docker buildx build instead of
docker build as well.
If you’re running Docker 18.06, you’ll have to enable experimental mode for the Docker daemon.
Using a Cache Mount
If you’re sick of re-downloading all external dependencies every time there’s a change to one of them, the cache mount can help you save time in the future.
Inside of your Dockerfile, add a mount flag, specifying which directories should be cached during the step.
RUN --mount=type=cache,target=/var/cache/apt ...
You can cache multiple directories this way, by adding multiple –mount flags to the same RUN instruction. Those directories will be preserved in between builds, even if the step has to be re-executed and wouldn’t be able to make use of the usual Docker cache. Neat!
Think of this feature like volumes which you can use during your build. If done right, this feature will help to speed up the rebuilds of your images.
Passing SSH Credentials
Accessing private repositories from within a Docker build used to be fiddly. As with other secrets, you didn’t want to leave behind your SSH credentials inside of your image layers.
With the new SSH mount type you can allow your Docker build to make use of your host’s SSH keys.
RUN --mount=type=ssh ...
No need to handle this kind of secrets. Speaking of secrets…
The secret mount type can give a single RUN command access to one or multiple secrets without leaving behind traces inside of the file system if used right. You can specify a secret from a file when running your build command:
docker build --secret id=yoursecret,src=/host/secret/file/path
You can give single RUN instructions access to this secret.
By default this creates a file inside of
/run/secrets/secretid, but you can
also specify a target path of your choice.
RUN --mount=type=secret,id=yoursecret ... RUN --mount=type=secret,id=yoursecret,target=/target/path/to/secret ...
The file is created and cleaned up automatically, so it won’t stick around in the image layer unless you write it to the file system in your command… Which you shouldn’t.
Give It A Try!
Using those new BuildKit features can make it easier to pass SSH credentials, handle build-time secrets and cache directories in between builds even if the layer needs to be rebuilt.
Using BuildKit is not the default yet. It’s relatively new and a few hidden gotchas might turn up with time. For example, BuildKit is not completely backwards-compatible with the default build engine when it comes to advanced features, but if you don’t have to preserve past workflows you shouldn’t need to worry about that.