Run Docker Containers using Podman and Libpod

Posted on 257 views

If you are familiar with containers, you must have heard of Docker and maybe Kubernetes (the orchestrator). Here comes Podman which brings innovation to container tools in the spirit of Unix commands which do “one thing” well. If you have used Docker before, Podman offers a similar experience as the Docker CLI.

How Docker CLI Works

The Docker CLI is a client/server operation and the Docker CLI communicates with the Docker engine when it wants to create or manipulate the operations of a container. This client/server architecture can lead into problems in production because one, you have to start the Docker daemon before Docker CLI comes alive. The Docker CLI then sends an API call to the Docker Engine to launch Open Container Initiative (OCI) Container runtime, in most cases runc, to start the container ( What this means is that the launched containers are child processes of the Docker Engine.

What is Podman?

What then is Podman? Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System.

Docker vs Podman

The major difference between Docker and Podman is that there is no daemon in Podman. It uses container runtimes as well for example runc but the launched containers are direct descendants of the podman process. This kind of architecture has its advantages such as the following:

  • Applied Cgroups or security constraints still control the container: Whatever cgroup constraints you apply on the podman command, the containers launched will receive those same constraints directly.
  • Advanced features of systemd can be utilized using this model: This can be done by placing podman into a systemd unit file and hence achieving more.

What about Libpod?

You must have seen Libpod on the title of this guide. Libpod just provides a library for applications looking to use the Container Pod concept, popularized by Kubernetes. It allows other tools to manage pods/container ( Podman is the default CLI tool for using this library. There are other two important Libraries that make Podman possible:

  • containers/storage – This library allows one to use copy-on-write (COW) file systems, required to run containers.
  • containers/image – This library that allows one to download and install OCI Based Container Images from containers registries like, Quay, and Artifactory, as well as many others (

These two libraries were built from the ground up to support multiple independent processes to interact with the libraries at the same time. A good example is that you can be running a full Kubernetes environment with CRI-O, building container images using Buildah and managing your containers and pods with Podman at the same time ( This brings the spirit of Unix commands which do “one thing” well. Such a combination of tools is not possible with Docker.

Install Podman on CentOS / Fedora / Ubuntu

Let us look at how Podman is installed in CentOS and Fedora

If you are on Ubuntu, please check:

For Debian, use:

Managing Container Images

Pull image using Podman:

podman pull ubuntu
podman pull centos
podman pull centos:8

To list downloaded images, use the command:

$ podman  images
REPOSITORY                 TAG      IMAGE ID       CREATED        SIZE   latest   3556258649b2   2 weeks ago    66.6 MB   latest   b7b28af77ffe   3 weeks ago    5.85 MB   latest   00bf7fdd8baf   4 weeks ago    119 MB   latest   9f38484d220f   4 months ago   209 MB

To remove an image, use -rmi option followed by image name/ID:

$ podman rmi 00bf7fdd8baf

$ podman rmi

Tagging images

You can add your custom name to images to make it more intuitive and to remind you what the image does in your set up

# podman tag 7698f282e524 webserver

# podman images                    
 REPOSITORY                 TAG      IMAGE ID       CREATED       SIZE   latest   7698f282e524   4 weeks ago   72.3 MB
 localhost/webserver        latest   7698f282e524   4 weeks ago   72.3 MB

Running Containers with Podman

To run a simple container using Ubuntu image which prints a message, use:

# podman run --rm ubuntu /bin/echo "Computing for Geeks" 
Computing for Geeks

To run a container in background (detached mode), use -d option.

podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/var/run/httpd -e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \
                  -e HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \
                  -e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \

This will return the container ID:

Trying to pull image source signatures
Copying blob d77ff9f653ce done
Copying blob aaf5ad2e1aa3 done
Copying blob 7692efc5f81c done
Copying config 25c76f9dcd done
Writing manifest to image destination
Storing signatures

Listing running containers

The Podman ps command is used to list creating and running containers.

$ podman ps
CONTAINER ID  IMAGE                                        COMMAND               CREATED        STATUS            PORTS                   NAMES
d2cdf0efb0dd  container-entrypo...  4 minutes ago  Up 4 minutes ago>8080/tcp  cranky_borg

# To include stopped / exited containers, use:
$ podman ps --all

Run a shell in a container

To access a container shell, use the options -it:

# podman run -it ubuntu bash
[email protected]:/#
[email protected]:/# apt update
 Get:1 bionic InRelease [242 kB]
 Get:2 bionic-security InRelease [88.7 kB]          
 Get:3 bionic-security/universe amd64 Packages [717 kB]
 Get:4 bionic-updates InRelease [88.7 kB]        
 Get:5 bionic-security/main amd64 Packages [535 kB]
 Get:6 bionic-backports InRelease [74.6 kB]

Searching in Podman

$ podman search httpd

Inspecting Containers

This displays the low-level information on containers and images identified by name or ID.

# podman inspect 024a277cc474
        "ID": "024a277cc4748ab48539c9ddea15d98c0e0bccc307506c44fbce12ec6c568dfc",
        "Created": "2019-06-14T10:58:07.764967058-04:00",
        "Path": "/bin/bash",
        "Args": [

See more on usage:

$ podman inspect --help

Removing containers

First list all running containers:

$ podman ps -a

CONTAINER ID  IMAGE                            COMMAND               CREATED        STATUS                    PORTS  NAMES
 024a277cc474  /bin/bash             3 minutes ago  Exited (0) 3 minutes ago         laughing_blackwell
 cf4267fb7a2b  bash                  4 hours ago    Exited (0) 2 hours ago           nostalgic_archimedes
 b800dd64ba11  /bin/bash             4 hours ago    Exited (0) 4 hours ago           optimistic_hypatia

To delete a single running container use the podman rm command followed by the container id:

$ podman rm 024a277cc474

To remove all containers, both running and stopped use:

podman rm $(podman ps -a -q)

Viewing the container’s logs

You can view the container’s logs with Podman as well:

$ podman logs --latest

You can also specify container ID:

$ podman ps
$ podman logs d2cdf0efb0dd

To follow the logs output in real-time, use:

$ podman logs -f  ContainerID
$ podman logs --follow=true --since 10m ContainerID

Show only last 10 lines in logs:

$ podman logs --tail 10 d2cdf0efb0dd

Viewing the container’s pids

Use podman top to view container’s pids.

$ podman top 


$ podman top d2cdf0efb0dd
USER      PID   PPID   %CPU    ELAPSED            TTY     TIME   COMMAND
default   1     0      0.000   29m22.496484247s   pts/0   0s     httpd -D FOREGROUND 
default   22    1      0.000   29m21.496767511s   pts/0   0s     /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat 
default   23    1      0.000   29m21.496866314s   pts/0   0s     /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat 
default   24    1      0.000   29m21.497020539s   pts/0   0s     /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat 
default   25    1      0.000   29m21.497127237s   pts/0   0s     /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat 
default   26    1      0.000   29m21.49723933s    pts/0   0s     httpd -D FOREGROUND 
default   27    1      0.000   29m21.497361006s   pts/0   0s     httpd -D FOREGROUND 
default   28    1      0.000   29m21.497459891s   pts/0   0s     httpd -D FOREGROUND 
default   29    1      0.000   29m21.497552695s   pts/0   0s     httpd -D FOREGROUND 

Checkpointing the container

Checkpointing a container stops the container while writing the state of all processes in the container to disk. This capability requires CRIU 3.11 or later installed on the system. See CRIU installation.

podman container checkpoint 


$ podman container checkpoint d2cdf0efb0dd

A container can later be restored and continue running at exactly the same point in time as the checkpoint.

podman container restore 

Migrate the container

First checkpoint the container on the source system:

podman container checkpoint  -e /tmp/checkpoint.tar.gz

Copy it to the destination server:

scp /tmp/checkpoint.tar.gz :/tmp

On the destination system, restore container:

podman container restore -i /tmp/checkpoint.tar.gz

Manage container pods with Podman

Podman pods are similar to the Kubernetes concept of Pods


Most of the interaction with pods is exposed through the podman pod commands:

$ podman pod --help
   podman pod - Manage container pods.

Pods are a group of one or more containers sharing the same network, pid and ipc namespaces.

   podman pod command [command options] [arguments...]

     create        Create a new empty pod
     exists        Check if a pod exists in local storage
     inspect       displays a pod configuration
     kill          Send the specified signal or SIGKILL to containers in pod
     pause         Pause one or more pods
     ps, ls, list  List pods
     restart       Restart one or more pods
     rm            Remove one or more pods
     start         Start one or more pods
     stats         Display percentage of CPU, memory, network I/O, block I/O and PIDs for containers in one or more pods
     stop          Stop one or more pods
     top           Display the running processes of containers in a pod
     unpause       Unpause one or more pods

   --help, -h  show help

The example below will create a pod called web

$ podman pod create --name web

This creates a pod without the extra attributes available on:

$ podman pod create --help

Confirm pod creation

$ podman pod list
0f565b11e9cb   web    Running   About a minute ago   1                 44cca777d12f

By default, the created pod will have a container called infra. The infra container is in sleep mode and its purpose is to hold the namespaces associated with the pod to allow podman to connect other containers to the pod:

$ podman ps -a --pod 
CONTAINER ID  IMAGE                 COMMAND  CREATED         STATUS             PORTS  NAMES               POD
44cca777d12f           23 minutes ago  Up 23 minutes ago         0f565b11e9cb-infra  0f565b11e9cb

Now that the pod is created, we can add a container to it:

podman run -dt --pod web alpine:latest top

You should now see the pod has two containers

$ podman ps -a --pod 
CONTAINER ID  IMAGE                            COMMAND  CREATED             STATUS                 PORTS  NAMES               POD
36ccace2d653  top      About a minute ago  Up About a minute ago         zen_hugle           0f565b11e9cb
44cca777d12f                      28 minutes ago      Up 28 minutes ago             0f565b11e9cb-infra  0f565b11e9cb

This how you’ll create a container and expose a port – root required for port binding.

sudo podman pod create -p 8080:80 --name web1
sudo podman run -dt --pod web1 -p 8080 nginx:latest

Note that you need to publish as many port as will be used during the pod creation. This can’t be changed after the creation.


Podman shows a lot of promise in the future of Containerization. In fact, Red Hat did not just remove the Docker container engine from OpenShift. It also removed the Docker container engine, along with the docker command, from Red Hat Enterprise Linux 8 entirely. Thank you for reading through.

Reference :


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.