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.