Podman and Buildah for Docker users – Red Hat Developer

I was recently asked on Twitter to better explain Podman and Buildah for someone familiar with Docker. Although there are many blogs and tutorials out there, which I’ll list later, we in the community haven’t centralized an explanation of how Docker users move from Docker to Podman to Buildah. Also, what role does Buildah play? Is Podman deficient in any way that we need both Podman and Buildah to replace Docker?

This article answers those questions and shows how to migrate to Podman.

How does Docker work?

First, let’s be clear about how Docker works; that will help us understand the motivation for Podman and also for Buildah. If you are a Docker user, you understand that there is a daemon process that needs to run to service all your Docker commands. I can’t pretend to understand the motivation behind this, but I imagine it seemed like a great idea, at the time, to do all the cool things that Docker does in one place and also provide a useful API for that process for future evolution. In the diagram below, we can see that the Docker daemon provides all the functionality needed to:

Extract and insert images from an


  • registry
  • Make copies of images in a local storage container and add layers to those
  • containers

  • Confirm containers and delete local container images from the host repository
  • Ask the kernel to run a container with the correct namespace and cgroup, etc.

Essentially, the Docker daemon does all the work with registers, images, containers, and the kernel. The Docker command line interface (CLI) prompts the daemon to do this on your behalf.

This article does not go into the detailed pros and cons of the Docker daemon process. There’s a lot to be said for this approach and I can see why, in the early days of Docker, it made a lot of sense. Suffice it to say that there were several reasons why Docker users were concerned about this approach as usage increased. To list a few:

  • A single process could be a single point of failure
  • .

  • This process owned all child processes (the running containers).
  • If an error occurred, there were orphaned processes
  • .

  • The creation of containers led to security vulnerabilities
  • .

  • All Docker operations had to be performed by a user (or users) with the same full root authority.

There are probably more. Whether these problems have been fixed or whether you disagree with this characterization is not something this article is going to discuss. We in the community believe that Podman has addressed many of these issues. If you want to take advantage of Podman’s enhancements, then this article is for you.

Podman’s approach is simply to interact directly with the image registry, with the image container and storage, and with the Linux kernel through the runC container runtime process (not a daemon).

Now that we’ve discussed some of the motivations, it’s time to discuss what that means for the user migrating to Podman. There are a few things to unpack here and we’ll get into each one separately:

  • Install Podman instead of Docker. You do not need to start or manage a daemon process such as the Docker daemon.
  • The commands you’re familiar with in Docker work the same for Podman.
  • Podman stores its containers and images in a different place than Docker.
  • Podman and Docker images are supported.
  • Podman does more than Docker for Kubernetes environments.
  • What is Buildah and why might I need it?

Installing Podman

If you are using Docker today, you can remove it when you decide to make the change. However, you may want to keep Docker while testing Podman. There are some useful tutorials and an impressive demo that you may want to run first so you can better understand the transition. An example in the demo requires Docker to show compatibility.

To install Podman

on Red Hat Enterprise Linux 7.6 or later, use the following; if you are using Fedora, replace yum with dnf: # yum

-y install podman Podman’s

commands are the same as

Docker’s When creating Podman, the goal was to make sure that Docker users could easily adapt. So all the commands you’re familiar with also exist with Podman. In fact, it is claimed that if you have existing scripts running Docker, you can create a docker alias for podman and all your scripts should work (docker alias = podman). Try. Of course, you must first stop Docker (systemctl stop docker). There is a package you can install called podman-docker that does this for conversion for you. Drop a script in /usr/bin/docker that runs Podman with the same arguments.

The commands you are familiar with (pull, push, compile, execute, commit, tag, etc.) exist with Podman. See the Podman manual pages for more information. One notable difference is that Podman has added some flags of convenience to some commands. For example, Podman has added -all (-a) flags for podman rm and podman rmi. Many users will find that very useful.

You can also run Podman from your normal non-root user in Podman 1.0 in Fedora. RHEL support is aimed at versions 7.7 and 8.1 onwards. Improvements in userspace security have made this possible. Running Podman as a normal user means that Podman, by default, will store images and containers in the user’s home directory. This is explained in the next section. For more information on how Podman runs as a non-root user, see Dan Walsh’s article: How Does Podman Work Without Roots?

Podman and container


When you write podman images for the first time, you might be surprised that you don’t see any of the Docker images you’ve already deleted. This is because the local Podman repository is in /var/lib/containers instead of /var/lib/docker. This is not an arbitrary change; this new storage structure is based on the Open Containers Initiative (OCI) standards.

In 2015, Docker, Red Hat, CoreOS, SUSE, Google, and other leaders in the Linux container industry created the Open Container Initiative to provide an independent body to manage the standard specifications for defining container images and the runtime. To maintain that independence, the container/image and container/storage projects were created on GitHub.

Since you can run podman without being root, there should be a separate place where podman can write images. Podman uses a repository in the user’s home directory: ~/.local/share/containers. This avoids making /var/lib/containers writable worldwide or other practices that could lead to potential security issues. This also ensures that each user has separate sets of containers and images and that everyone can use Podman simultaneously on the same host without stepping on each other. When users are done with their work, they can submit to a common registry to share their image with others.

Docker users who come to Podman find that knowing these locations is useful for debugging and for the important rm-rf/var/lib/containers, when you just want to start over. However, once you start using Podman, you’ll probably start using the new -all option for podman rm and podman rmi instead.

Container images are compatible between Podman

and other runtimes Despite

new locations for local repositories, images created by Docker or Podman are compatible with the OCI standard. Podman can push and pull from popular container logs like Quay.io and Docker hub, as well as private logs. For example, you can extract the latest Fedora image from the Docker hub and run it using Podman. Not specifying a record means that Podman will search by default through the records listed in the registries.conf file, in the order in which they are listed. An unmodified registries.conf file means that you will first search the Docker hub.

$ podman pull fedora:latest $ podman run -it fedora bash

Images sent to an image registry by Docker can be downloaded and executed by Podman. For example, an image (myfedora) that I created using Docker and pushed to my Quay.io repository (ipbabble) using Docker can be extracted

and run with Podman as follows: $podman pull quay.io/ipbabble/myfedora:latest$ podman run -it myfedora bash

Podman provides capabilities in its command line push and pull commands to gracefully move images from /var/lib/docker to /var/lib/containers and vice versa. For example

: $ podman push myfedora docker-daemon:myfedora:latest

Obviously, leaving out the docker-previous daemon will be sent by default to the Docker hub. Using quay.io/myquayid/myfedora will send the image to the Quay.io registry (where myquayid below is your personal Quay.io account):

$ podman push myfedora quay.io/myquayid/myfedora:latest

If you are ready to remove Docker, you must close the daemon and then delete the Docker package using the package manager. But first, if you have images you created with Docker that you want to keep, you need to make sure those images are sent to a registry so you can download them later. Or you can use Podman to pull each image (for example, fedora) from the host Docker repository to the Podman OCI-based repository. With RHEL you can run the following

: # systemctl stop docker # podman pull docker-daemon:fedora:latest # yum -y remove docker # optional Podman helps

users move to

Kubernetes Podman

provides some additional features that help developers and operators in Kubernetes environments. There are additional commands provided by Podman that are not available in Docker. If you’re familiar with Docker and are considering using Kubernetes/OpenShift as your container platform, Podman can help.

Podman can generate a Kubernetes YAML file based on a running container using podman generate kube. The podman pod command can be used to help debug running Kubernetes pods alongside standard container commands. For more details on how Podman can help you transition to Kubernetes, see the following article by Brent Baude: Podman can now ease the transition to Kubernetes and CRI-O.

What is Buildah and why would I use it?

Buildah actually came first. And maybe that’s why some Docker users get a little confused. Why do these Podman evangelists also talk about Buildah? Podman doesn’t make constructions?

Podman does builds and for those familiar with Docker, the build process is the same. You can build using a Dockerfile using podman build or you can run a container and make many changes and then commit those changes to a new image tag. Buildah can be described as a superset of commands related to creating and managing container images and therefore has much more granular control over images. The Podman build command contains a subset of the Buildah functionality. It uses the same code as Buildah to build.

The most powerful way to use Buildah is to write Bash scripts to create your images, similar to how you would write a Dockerfile.

I like to think of evolution as follows. When Kubernetes was moved to CRI-O based on the OCI runtime specification, there was no need to run a Docker daemon and therefore no need to install Docker on any host in the Kubernetes cluster to run pods and containers. Kubernetes could call CRI-O and could call runC directly. This, in turn, initiates container processes. However, if we want to use the same Kubernetes cluster to do builds, as in the case of OpenShift clusters, then we needed a new tool to perform builds that didn’t require the Docker daemon and subsequently required Docker to be installed. Such a tool, based on the container/storage and container/image projects, would also eliminate the security risk of the Docker daemon socket opened during builds, which worried many users.

Buildah (named for fun because of Dan Walsh’s Boston accent when pronouncing “builder”) fits into this project. For more information about Buildah, see buildah.io and specifically refer to the blog and tutorial sections.

There are a couple of additional things professionals should understand about Buildah: it

  1. allows for more precise control of image layer creation. This is a feature that many container users have been asking for for a long time. It is desirable to make many changes in a single layer.
  2. Buildah’s run command is not the same as Podman’s run command. Because Buildah is for creating images, the run command is essentially the same as the Dockerfile RUN command. In fact, I remember the week this was made explicit. I was foolishly complaining that some port or mount I was testing wasn’t working as I expected. Dan (@rhatdan) chimed in and said that Buildah should not support the operation of containers in that way. No port assignment. No volume mounting. Those flags were removed. Instead, buildah run is for executing specific commands to help build a container image, for example, buildah run dnf -y install nginx.
  3. Buildah can build images from scratch, i.e. images with nothing in them. Nothing. In fact, looking at container storage created as a result of a buildah command from scratch produces an empty directory. This is useful for creating very lightweight images that contain only the packages needed to run the application.

A good example of a use case for a draft build is to consider development images versus staging or production images of a Java application. During development, a Java application container image may require the Java compiler and Maven and other tools. But in production, you may only need the Java runtime and its packages. And by the way, you also don’t need a package manager like DNF/YUM or even Bash. Buildah is a powerful CLI for this use case. See diagram below. For more information, see Create a Buildah container image for Kubernetes and also this Buildah getting started demo.

Going back to the history of evolution… Now that we had solved the Kubernetes runtime issue with CRI-O and runC, and solved the build issue with Buildah, there was still a reason Docker was still needed on a Kubernetes host: debugging. How can we debug container issues on a host if we don’t have the tools to do so? We’d have to install Docker, and then we’re back to where we started with the Docker daemon on the host. Podman solves this problem.

Podman becomes a tool that solves two problems. It allows operators to browse containers and images with commands they are familiar with. And it also provides developers with the same tools. So, Docker users, developers, or operators can move to Podman, perform all the fun tasks they’re familiar with when using Docker, and do so much more.


I hope this article was helpful and helped you migrate to using

Podman (and Buildah) with confidence and success.

For more information:

  • Podman.io and Buildah.io project github.com/containers project websites
  • (participate,

  • get the source, see what’s being developed):
    • libpod (Podman
    • )

    • buildah
    • image (code for

    • working with OCI container images) storage (code for local images
    • and container storage)

Related Articles

Daemonless containers: Podman and Buildah available in RHEL

  • 7.6 and RHEL 8 Beta
  • Podman: Managing pods and containers in a local container runtime Managing containerized

  • system services with Podman (Use systemd to manage your podman containers)
  • Create a Buildah container image for
  • Kubernetes

  • Podman can now ease the transition to Kubernetes and CRI-O
  • Security Considerations for Container Runtimes (Video of Dan Walsh’s KubeCon 2018 Talk
  • )

  • Developing and Deploying IoT Edge with Containers via OpenShift: Part 1 (Building and Testing ARM64 Containers on OpenShift Using Podman, qemu, binfmt_misc, and Ansible)

Last updated: March 27, 2023

Contact US