Using Buildah to build images and manage containers
With the steady advancement of alternative tooling to the docker ecosystem, I thought it would be a good time to look into the different tooling around building, managing and running images. Buildah is a really interesting tool that is providing a alternative approach to containers and images. The official site provides really good instructions on how to build and run buildah. So the point of the following post is to just write my experience over the last few days of using buildah as an alternative to using docker.
Buildah differences to Docker
Buildah is not a completely different tooling system from docker and if you are familiar with docker it will not take a lot of learning to get used to using buildah. For example the following commands should feel pretty similar from the docker experience.
$ buildah ps # Returns the set of running containers $ buildah images # Returns the set of downloaded images
And running buildah --help
will return the possible commands. Buildah also supports concepts such as building an image
from a Dockerfile using the command buildah bud
. The big difference is how the containers are managed and run, unlike
Docker, buildah does not require root access. As a result of that, buildah should be considered more secure in comparison.
Dockerfile
If you already have a Dockerfile you can easily build a image using buildah. For example assuming that we have the following Dockerfile which builds and deploys a simple web site using nginx.
FROM nginx:latest
COPY public /usr/share/nginx/html
To create a image from the above Dockerfile you would execute docker build . -t <image_name>
. And you would be
able to start the container using that image by executing docker run -it --rm <image_name>
. Now assume that you wanted
to adjust the image, you would then probably adjust the Dockerfile with a new entry such as the following
FROM nginx:latest
LABEL "customized nginx server"
COPY public /usr/share/nginx/html
And then running the docker build
command again. In simple examples the image building lifecycle is not really a problem,
but with more complex images it can become painful to iterate over different image combinations.
Buildah does things a little differently, in that the image layers can be built using direct commands instead of a image
definition file (We can use that as well). Using the above Dockerfile you would be able to build an image by running
the command buildah bud . -t <image_name>
. But you could also build the image running direct commands instead. For
example if you wanted to use buildah commands to build the image you would execute the following
#!/bin/bash
ctr=$(buildah from nginx:latest)
buildah config --label="customized nginx server" "$ctr"
buildah add "$ctr" public /usr/share/nginx/html
buildah commit "$ctr" customized_nginx
The big advantage over the traditional Dockerfile is that you can quickly iterate on a image build until you are happy
with the result. You can also inspect the image state at any step, for example if you wanted to validate the state of
the image you would be able to execute commands by running buildah run "$ctr" bash
.
I am really impressed with the state of the tooling around containers. It is impressive to see the environment mature and fresh ideas being explored in the container world. The only drawback to buildah that I can see is that it is not able to just run containers, and you will need another engine for actually running containers. Podman is normally the goto suggestion, but any OCI capable engines can be used.