A simple way of creating containerized applications

Buildah: Build containers fast and easy without Docker

William Henry
© Shutterstock /  Constantin Stanciu

Linux containers are gaining an ever stronger foothold in the IT of modern companies. For this reason, developers need a simple way of creating containerized applications. Buildah makes it easy to build containers without the need for the overhead required by Docker.

Linux containers are an efficient means of developing and deploying new applications. Container technologies package and isolate apps together with the entire runtime environment. As a result, the containers are quickly ready for operation and even more portable than traditional applications since they contain the entire application environment.

There are two aspects of the container environment that are very important: On the one hand, Linux containers are undergoing continued development; in particular, the Open Container Initiative (OCI) is a key driver for innovation. On the other hand, several misunderstandings regarding the Linux container architecture persist. The following needs to be made clear: Containers do not run on Docker. Containers are processes that run on the Linux kernel. Therefore, containers are Linux. Moreover, Docker daemon is only one of many user space tools and libraries that communicate with the Linux kernel in order to create containers.

Buildah is an excellent example of these two aspects: when creating containers and for innovative ongoing refinement. Buildah makes it possible to create containers without using Docker, which means that users can implement Docker- and OCI-compliant container images with Buildah without the need for executing a container runtime daemon.

Developers normally need to use a number of tools and daemons to create a Linux container image. In contrast, the Buildah command line tool strips down the requirements for creating or modifying container images to the basics. The Buildah project is based on the OCI standard for container images. Buildah provides a simple command line interface (CLI) for creating OCI-compliant images by drawing on open source-based containers/image and containers/storage projects (on GitHub). In so doing, Buildah greatly streamlines the container build pipeline.

Simple container creation using Buildah

There are several ways in which Buildah is remarkably different from creating images with Docker. Buildah can create a container using a container image and a Dockerfile, or it can be started with an empty image. Furthermore, the process has the capability to draw on external packaging tools rather than requiring a package manager within the image itself. The reason for this is that you can use Buildah to build using an existing image from inside a running container (similar to Docker) or you can build the image directly on the storage volume (containers/storage) without running the container. Docker requires a running container, Buildah does not.

The difference using Buildah from building images with the Docker command results in various benefits:

  • The size of the created image is smaller.
  • Improved security of the image because the software used to create the container (such as gcc, make, and dnf) is not contained in the image.
  • Fewer resources are required to move images owing to their smaller size.
  • You can create a single layer image which can be more suited to test and production environments.
  • Better secrets handling for subscriptions or credentials to secure registries.

Buildah generally offers a wide range of options for creating and working with containers; for example, there are more than a dozen options for using the Buildah command. These are some of the main commands and actions:

  • Creating a container based on a different image or from scratch: Create a new container (container root file system) based on an available base image (buildah from <image name>) or from scratch (buildah from scratch).
  • Creating a container using a Dockerfile: Use a Dockerfile to build a new container image (buildah bud).
  • Requesting information on containers or images: Verify metadata that is associated with the container or image (buildah inspect).
  • Mounting a container: Mount a container root file system on the host to add or modify content (buildah mount).
  • Designing a new container layer: Use the contents of a container root file system as the file system layer to add content to a new image (buildah commit).
  • Deleting a container or image: Delete a container (buildah rm) or container image (buildah rmi).

Using Buildah to quickly create new containers

Users can create a new container that has no content and the bare minimum container metadata (scratch container), instead of starting with a base image. A script on GitHub, called, shows running the Buildah container using Podman as well as the Docker compatibility. This example also proves that there is no need for a Docker daemon.

Another example shows how convenient it is to add a web service (httpd) to a container and configure it to be executable. It illustrates how to create an image so that it can be managed directly by the local Docker service (Docker daemon stored locally in /var/lib/docker).

Starting with the creation of a scratch container:

# buildah from scratch

Create an empty container that can be mounted as follows:

# scratchmnt=$(buildah mount working-container)
# echo $scratchmnt /var/lib/containers/storage/devicemapper/mnt/cc92011e9a2b077d03a97c0809f1f3e7fef0f29bdc6ab5e86b85430ec77b2bf6/rootfs

Initialize an RPM database in the scratch image and add a Red Hat release package that contains additional required files for using the RPM:

# rpm --root $scratchmnt –initdb
# yum install yum-utils       (if not already installed)
# yumdownloader --destdir=/tmp redhat-release-server
# rpm --root $scratchmnt -ihv /tmp/redhat-release-server*.rpm

Installing the httpd service in the scratch directory:

# yum install -y --installroot=$scratchmnt httpd

Add text to an index.html file in the container for subsequent tests

# echo "Your httpd container from scratch worked." > $scratchmnt/var/www/html/index.html

‘buildah config’ options are used to run the httpd daemon by de-fault when the container is started:

# buildah config --entrypoint "/usr/sbin/httpd -DFOREGROUND" working-container
# buildah config --port 80/tcp working-container
# buildah commit working-container docker-daemon:myhttpd:latest

Based on a default setting, the ‘buildah commit’ command adds the repository name to the image name and copies the image to the storage area of the local Docker service (/var/lib/docker). Then the image ID can be used for operating the new image as a container using the ‘docker’ command:

# docker images
REPOSITORY       TAG     IMAGE ID          CREATED         SIZE   latest   47c0795d7b0e   9 minutes ago   665.6 MB
# docker run -p 8080:80 -d --name httpd-server 47c0795d7b0e
# curl localhost:8080
Your httpd container from scratch worked.

The example above shows how quick and convenient it is to create a container using Buildah. What’s more, there is no need for a container runtime or daemon. The fact that Buildah does not require a daemon not only makes building a container easier, but it also streamlines operation since the host on which it is de-ployed does not require special infrastructure.

In addition to building and operating containers, Buildah offers one more key advantage: It is a command line tool. This means that developers can integrate it into existing pipelines for application creation with much greater ease.


William Henry

William Henry is a Senior Consulting Engineer at Red Hat.

Inline Feedbacks
View all comments