When to you Docker vs Podman? A developer's perspective

Differences between Docker and Podman

Docker is a container management technology. Podman is also a container technology. You can use either for building container images and storing those images in a repository. You can also use either Docker or Podman to pull container images from a registry and then run them in a target environment.

However, the technologies do have differences. First, while Docker has an underlying daemon, Podman uses a slightly different technology to create containers. Second, Podman, as the name implies, allows users to create pods. A pod is a way to group containers together under a common organizational name. Docker does not support pods. There are other subtle differences, but at a high level, these two differences are the most pronounced.

Let’s look at the details of each.

Docker vs Podman comparison

As mentioned above Docker uses a daemon to manage container activity on a machine. Docker uses the containerd daemon. The containerd daemon does the work of pulling a container image from a container registry. Then, containerd turns over the process of creating the container to a low-level runtime named runc

Podman on the other hand takes what’s advertised as a daemon-less approach using a technology named conmon. conman does the work of getting container images, creating containers, and storing state information about a container. While conman differs from containerd in that conmon has a smaller memory footprint, both containerd and conmon delegate container creation to a low-level container runtime such as runc.

One of the key features of Podman is that it allows you to create pods. A pod is an organizational unit for containers. Pods are an essential part of the Kubernetes container orchestration framework. In fact, you can use Podman to create manifest files that describe pods in a declarative format. These manifest files, which are written in YAML, can be consumed by Kubernetes.

Creating a pod using Podman

Let’s take a look at how to create a pod and then add some containers to it. Then, once the pod is created we can export the pod definition to a Kubernetes manifest file. Of course, the steps to follow assume that you have Podman installed in your computing environment.

In order to create a pod with Podman you execute the following command, which creates a pod named, my-pod

podman pod create --name my-pod

Then run the following command to see that the pod has been created.

podman pod list

You’ll get output as follows:

POD ID         NAME     STATUS    CREATED          # OF CONTAINERS   INFRA ID
7ebb4bef22c1   my-pod   Created   10 seconds ago   1                 ab55ddb62bdc

Notice that the pod has one container. This is the default container that handles the pod’s interaction with your local machine. Still, for all intents and purposes, this pod hasn’t any containers, so let’s add two.

We’ll create the first container for the pod.

podman run --pod my-pod -d alpine sleep infinity

Then we’ll create the second container.

podman run --pod my-pod -d nginx:alpine

Let’s get a listing of the pod again.

podman pod list

This time the contents of the pod will reflect that default container plus the two we just created.

POD ID         NAME     STATUS    CREATED         # OF CONTAINERS   INFRA ID
7ebb4bef22c1   my-pod   Running   4 minutes ago   3                 ab55ddb62bdc

Notice that the number of containers in the pod has increased to 3. Now, let’s generate the manifest file that we can use to create this pod in Kubernetes

podman generate kube -f pod.yml my-pod

Executing podman generate as shown above will create a file named, pod.yml. The contents of pod.yml are shown below in Listing 1.

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2021-03-30T21:10:56Z"
  labels:
    app: my-pod
  name: my-pod
spec:
  containers:
  - command:
    - nginx
    - -g
    - daemon off;
    env:
    - name: PATH
      value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
      value: my-pod
    - name: container
      value: podman
    - name: NGINX_VERSION
      value: 1.19.9
    - name: NJS_VERSION
      value: 0.5.3
    - name: PKG_RELEASE
      value: "1"
    image: docker.io/library/nginx:alpine
    name: eloquentvolhard
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
    workingDir: /
  - command:
    - sleep
    - infinity
    env:
    - name: PATH
      value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm

A Kubernetes manifest file that describes a pod generated by Podman

Granted, the ability to create pods that are consumable by Kubernetes is in some sense a “nice to have.” But, the feature does demonstrate the added power of Podman.

Putting it All Together

The important thing to understand about the difference between Docker and Podman is that while both are container management tools, the internals of Docker are different than the internals of Podman. At the operational level, you can use either to create and destroy containers. Docker had been around longer than Docker so there is widespread acceptance of the technology. It’s proven to be reliable. Podman is still a maturing technology. But, the added efficiency of its internals as well as the ability to work with pods makes it an attractive way to do container management.

Get hands-on with Podman?

All the commands and steps shown in this article are part of a Podman tutorial on the Katacoda. Katacoda is an interactive learning environment that allows users to learn a technology by using a technology. The Katacoda tutorial, Creating a Pod using Podman is located here.