My Little Buildah and Podman Cheat Sheet


A brief cheat sheet of some common commands and examples for using buildah and podman to build and run OCI containers without the docker daemon for reference.

Buildah

Creating an OCI working container image using the existing image python:alpine as the base.

container=$(buildah from python:alpine)

Mount the working container file system

mountpoint=$(buildah mount $container)

Creating a directory in the image file system

mkdir $mountpoint/app

Copying files into the container image file system

buildah copy $container ./requirements.txt /app/

Configuring environmental variables

buildah config --env FLASK_APP=api.py $container

Configuring a working directory

buildah config --workingdir /app $container

Running a command inside of the image, e.g. to install Python packages

buildah run $container pip3 install -r /app/requirements.txt

Set the container CMD

buildah config --cmd "/usr/local/bin/python3 /app/api.py" $container

Add a label

buildah config --label "My Container" $container

Define an exposed port

buildah config --port 5000 $container

Create the image

buildah commit --squash $container my-container-image

Unmount the working container file system

buildah unmount $container

Remove the working container

buildah rm $container

Buildah with Red Hat Enterprise Linux 8

I came across a few issues when using Buildah on RHEL 8 when running rootless containers. The first issue I encountered was when trying to run a pip install during the container creation script.

buildah run $container pip3 install -r /app/requirements.txt

Running this rootless resulted in the below output.

cannot specify gid= mount options for unmapped gid in rootless containers

error running container: error creating container for [pip3 install -r /app/requirements.txt]: : exit status 1

error while running runtime: exit status 1

ERRO[0000] exit status 1 

The first thing I tried after some research was to use the buildah unshare command. To run this, I used a bash script similar to the below and executed the command like this.

buildah unshare ./myscript.sh

However, this resulted only in a new error.

cannot specify gid= mount options for unmapped gid in rootless containers

error running container: error creating container for [/usr/local/bin/pip3 install -r /app/requirements.txt]: : exit status 1

error while running runtime: exit status 1

After some more research, I found the solution. Running the buildah unshare command using the bash script is still required in addition to this change.

buildah run --isolation rootless $container pip3 install -r /app/requirements.txt

Podman

Noting, Podman syntax follows the docker command line syntax mostly.

Create a volume

podman volume create my-container-data-volume

Creating a container from the image created by Buildah

podman run --detach --name my-container -p 5000:5000 -v my-container-data-volume:/data localhost/my-container-image

Stop a container

podman stop my-container

Delete the container

podman rm my-container

Filtering output

podmanlist --all --filter "name=my-container" -- format {{.Names}}

Podman with Red Hat Enterprise Linux 8

Similarly, with Buildah, I also came across issues when using Podman on RHEL 8 when running rootless containers. The output for the problem I encountered is below.

ERRO[0000] 'overlay' is not supported over xfs at "/home/jason/.local/share/containers/storage/overlay"

ERRO[0000] [graphdriver] prior storage driver overlay failed: kernel does not support overlay fs: 'overlay' is not supported over xfs at "/home/jason/.local/share/containers/storage/overlay": backing file system is unsupported for this graph driver

error creating libpod runtime: kernel does not support overlay fs: 'overlay' is not supported over xfs at "/home/jason/.local/share/containers/storage/overlay": backing file system is unsupported for this graph driver

error creating libpod runtime: kernel does not support overlay fs: 'overlay' is not supported over xfs at "/home/jason/.local/share/containers/storage/overlay": backing file system is unsupported for this graph driver

 

Creating required volumes

error creating libpod runtime: kernel does not support overlay fs: 'overlay' is not supported over xfs at "/home/jason/.local/share/containers/storage/overlay": backing file system is unsupported for this graph driver

Again after some research, I found the solution well documented here. tl;dr the syntax of the file $HOME/.config/containers/storage.conf was using camel case and that needed to be removed — the updated version looks similar to the below.

[storage]
   driver = "overlay"
   runroot = "/run/user/1000"
   graphroot = "/home/jason/.local/share/containers/storage"
   [storage.options]
     mount_program = "/usr/bin/fuse-overlayfs"

Shell Script

Sample rough shell script to make it easier to do the above.

#!/bin/bash

#
# MY CONTAINER
#

buildah_my_container()
{
    echo -e "BUILDING CONTAINER"
    container=$(buildah from python:alpine)
    echo -e "Container name: $container \n"
    mountpoint=$(buildah mount $container)
    echo -e "Mount point: $mountpoint \n"
    mkdir $mountpoint/app
    echo -e "Copy files to container rootfs\n"
    buildah copy $container ./requirements.txt /app/
    echo -e "Setup envs\n"
    buildah config --env FLASK_APP=api.py $container
    echo -e "Configure workingdir\n"
    buildah config --workingdir /app $container
    echo -e "Install python requirements\n"
    buildah run $container pip3 install -r /app/requirements.txt
    echo -e "Configure the container CMD\n "
    buildah config --cmd "/usr/local/bin/python3 /app/api.py" $container
    echo -e "Adding Metadata\n"
    buildah config --label "My Container" $container
    echo -e "Commit and squash the container\n"
    buildah commit --squash $container my-container-image
    echo -e "Removing the container"
    buildah unmount $container
    buildah rm $container
}

buildah_delete_container_images()
{
    echo -e "\nDeleting container image"
    buildah rmi my-container-image
}

podman_my_container()
{
    echo -e "\nCreating required volumes"
    podman volume create my-container-data-volume
    podman run --detach --name my-container-image -p 5001:5000 -v my-container-data-volume:/data localhost/my-container-image
}

podman_start_my_container()
{
    echo -e "\nStarting my container in podman"
    podman_my_container
}

podman_delete_my_container()
{
    echo -e "\nStopping my container"
    podman stop my-container
    podman rm my-container
}

PARAMS=""
while (( "$#" )); do
  case "$1" in
    -a|--all)
      AARG=$1
      shift
      ;;
    -c|--build-container)
      CARG=$2
      shift 2
      ;;
    -s|--start-container)
      SCARG=$2
      shift 2
      ;;
    -dai|--delete-all-images)
      DAARG=$1
      shift
      ;;
    -dac|--delete-all-containers)
      DACARG=$1
      shift
      ;;
    -sac|--start-all-containers)
      SAARG=$1
      shift
      ;;
    -h|--help)
      HARG=$1
      shift
      ;;
    --) # end argument parsing
      shift
      break
      ;;
    -*|--*=) # unsupported flags
      echo "Error: Unsupported flag $1" >&2
      exit 1
      ;;
    *) # preserve positional arguments
      PARAMS="$PARAMS $1"
      shift
      ;;
  esac
done
# set positional arguments in their proper place
eval set -- "$PARAMS"

if [ "$AARG" ]
then
    buildah_my_container
fi

if [ "$CARG" ]
then
    if [ "$CARG" = "my_container" ]
    then
        buildah_my_container
    else
        echo "Unknown container"
    fi
fi

if [ "$SCARG" ]
then
    if [ "$SCARG" = "my_container" ]
    then
        podman_my_container
    else
        echo "Unknown container"
    fi
fi

if [ "$DAARG" ]
then
    buildah_delete_container_images
fi

if [ "$SAARG" ]
then
    podman_start_my_container
fi

if [ "$DACARG" ]
then
    podman_delete_my_container
fi

if [ "$HARG" ]
then
    echo -e "\nA command line utility for building my container images using buildah.\n"
    echo -e "Note:"
    echo -e "   - This utility must be run as root"
    echo -e ""
    echo -e "OPTIONS:"
    echo -e "   --all, -a                           build all containers image [my_container]"
    echo -e "   --build-container value, -c value   build provided container image"
    echo -e "   --delete-all-images, -dai           delete all container images"
    echo -e "   --delete-all-containers, -dac       delete all container containers"
    echo -e "   --start-all-containers, -sac        start all container containers"
    echo -e "   --start-container value, -s value   start the provided container"
fi

Helpful Links

Some helpful links: