Chapter 19. Building container images with Buildah
Buildah facilitates building OCI container images that meet the OCI Runtime Specification. With Buildah, you can create a working container, either from scratch or using an image as a starting point. You can create an image either from a working container, using the instructions in a Containerfile, or by using a series of Buildah commands that emulate the commands found in a Containerfile.
19.1. The Buildah tool Copy linkLink copied to clipboard!
Buildah is a command-line tool for creating Open Container Initiative (OCI) container images and a working container from the image. With Buildah, you can create containers and container images in different ways:
- Container image from scratch
-
You can create minimal container images from scratch with the
buildah from scratchcommand. Minimal container images have the following benefits: Avoid including any unnecessary files or dependencies, enhanced security, and optimized performance. For more information, see Creating images from scratch with Buildah. - Containers from a container image
-
You can create a working container from the container image by using the
buildah from <image>command. Then you can modify the container by using thebuildah mountandbuildah copycommands. For more information, see Working with containers using Buildah. - Container image from an existing container
-
You can create a new container image by using the
bulidah commitcommand. Optionally, you can push the newly created container image to a container registry by using thebuildah pushcommand. For more information, see Working with containers using Buildah. - Container image from instructions in a Containerfile
-
You can build a container image from instructions in a
Containerfileby using thebuildah buildorbuildah budcommands. For more information, see Building and image from a Containerfile using Buildah.
Using Buildah differs from building images with the docker command in the following ways:
- No Daemon
- Buildah requires no container runtime daemon.
- Base image or scratch
- You can build an image based on another container or start from scratch with an empty image .
- Reduced image size
-
Buildah images do not include build tools, such as
gcc,make, anddnf. As a result, the images are more secure and you can more easily transport the images. - Compatibility
-
You can easily migrate from Docker to Buildah because Buildah supports building container images with a Containerfile. You can use the same commands inside a
Containerfileas in aDockerfile. - Interactive image building
- You can build images step-by-step interactively by creating and committing changes to containers.
- Simplified image creation
-
You can create
rootfs, generate JSON files, and build OCI-compliant images with Buildah. - Flexibility
- You can script container builds directly in Bash.
19.2. Buildah and Podman relationship Copy linkLink copied to clipboard!
Buildah is a daemonless tool for building Open Container Initiative (OCI) images. Buildah’s commands replicate the commands of a Containerfile. Buildah provides a lower-level interface to build images without requiring a Containerfile. You can also use other scripting languages to build container images. Although you can create containers with Buildah, Buildah containers are primarily created temporarily for the purpose of defining the container image.
Podman is a daemonless tool for maintaining and modifying OCI images, such as pulling and tagging. You can create, run, and maintain containers created from those images.
Some of the Podman and Buildah commands have the same names but they differ in some aspects:
run-
The
podman runcommand runs a container. Thebuildah runcommand is similar to the RUN directive in aContainerfile. commit- You can commit Podman containers only with Podman and Buildah containers only with Buildah.
rm- You can remove Podman containers only with Podman and Buildah containers only with Buildah.
The default container storage for Buildah is /var/lib/containers/storage for root users and $HOME/.local/share/containers/storage for non-root users. This is the same as the location the CRI-O container engine uses for storing local copies of images. As a result, the images pulled from a registry by either CRI-O or Buildah, or committed by the buildah command, are stored in the same directory structure. However, even though CRI-O and Buildah currently can share images, they cannot share containers.
19.3. Installing Buildah Copy linkLink copied to clipboard!
Install the Buildah tool using the dnf command.
Procedure
Install the Buildah tool:
dnf -y install buildah
# dnf -y install buildahCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the help message:
buildah -h
# buildah -hCopy to Clipboard Copied! Toggle word wrap Toggle overflow
19.4. Getting images with Buildah Copy linkLink copied to clipboard!
Use the buildah from command to create a new working container from scratch or based on a specified image as a starting point.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Create a new working container based on the
registry.redhat.io/ubi9/ubiimage:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List all images in local storage:
buildah images
# buildah images REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/ubi9/ubi latest 272209ff0ae5 2 weeks ago 234 MBCopy to Clipboard Copied! Toggle word wrap Toggle overflow List the working containers and their base images:
buildah containers
# buildah containers CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME 01eab9588ae1 * 272209ff0ae5 registry.access.redhat.com/ub... ubi-working-containerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
19.5. Building an image from a Containerfile with Buildah Copy linkLink copied to clipboard!
Use the buildah bud command to build an image using instructions from a Containerfile.
The buildah bud command uses a Containerfile if found in the context directory, if it is not found the buildah bud command uses a Dockerfile; otherwise any file can be specified with the --file option. The available commands that are usable inside a Containerfile and a Dockerfile are equivalent.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Create a
Containerfile:cat Containerfile FROM registry.access.redhat.com/ubi9/ubi ADD myecho /usr/local/bin ENTRYPOINT "/usr/local/bin/myecho"
# cat Containerfile FROM registry.access.redhat.com/ubi9/ubi ADD myecho /usr/local/bin ENTRYPOINT "/usr/local/bin/myecho"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a
myechoscript:cat myecho echo "This container works!"
# cat myecho echo "This container works!"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Change the access permissions of
myechoscript:chmod 755 myecho
# chmod 755 myechoCopy to Clipboard Copied! Toggle word wrap Toggle overflow Build the
myechoimage usingContainerfilein the current directory:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List all images:
buildah images
# buildah images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/myecho latest b28cd00741b3 About a minute ago 234 MBCopy to Clipboard Copied! Toggle word wrap Toggle overflow Run the
myechocontainer based on thelocalhost/myechoimage:podman run --name=myecho localhost/myecho
# podman run --name=myecho localhost/myecho This container works!Copy to Clipboard Copied! Toggle word wrap Toggle overflow List all containers:
podman ps -a
# podman ps -a 0d97517428d localhost/myecho 12 seconds ago Exited (0) 13 seconds ago myechoCopy to Clipboard Copied! Toggle word wrap Toggle overflow
You can use the podman history command to display the information about each layer used in the image.
19.6. Creating images from scratch with Buildah Copy linkLink copied to clipboard!
Instead of starting with a base image, you can create a new container that holds only a minimal amount of container metadata.
When creating an image from scratch container, consider:
- You can copy the executable with no dependencies into the scratch image and make a few configuration settings to get a minimal container to work.
-
You must initialize an RPM database and add a release package in the container to use tools like
dnforrpm. - If you add a lot of packages, consider using the standard UBI or minimal UBI images instead of scratch images.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
You can adds a web service httpd to a container and configures it to run.
Create an empty container:
buildah from scratch
# buildah from scratch working-containerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Mount the
working-containercontainer and save the mount point path to thescratchmntvariable:scratchmnt=$(buildah mount working-container) echo $scratchmnt
# scratchmnt=$(buildah mount working-container) # echo $scratchmnt /var/lib/containers/storage/overlay/be2eaecf9f74b6acfe4d0017dd5534fde06b2fa8de9ed875691f6ccc791c1836/mergedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize an RPM database within the scratch image and add the
redhat-releasepackage:dnf install -y --releasever=8 --installroot=$scratchmnt redhat-release
# dnf install -y --releasever=8 --installroot=$scratchmnt redhat-releaseCopy to Clipboard Copied! Toggle word wrap Toggle overflow Install the
httpdservice to thescratchdirectory:dnf install -y --setopt=reposdir=/etc/yum.repos.d \ --installroot=$scratchmnt \ --setopt=cachedir=/var/cache/dnf httpd# dnf install -y --setopt=reposdir=/etc/yum.repos.d \ --installroot=$scratchmnt \ --setopt=cachedir=/var/cache/dnf httpdCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
$scratchmnt/var/www/html/index.htmlfile:mkdir -p $scratchmnt/var/www/html echo "Your httpd container from scratch works!" > $scratchmnt/var/www/html/index.html
# mkdir -p $scratchmnt/var/www/html # echo "Your httpd container from scratch works!" > $scratchmnt/var/www/html/index.htmlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Configure
working-containerto run thehttpddaemon directly from the container:buildah config --cmd "/usr/sbin/httpd -DFOREGROUND" working-container buildah config --port 80/tcp working-container buildah commit working-container localhost/myhttpd:latest
# buildah config --cmd "/usr/sbin/httpd -DFOREGROUND" working-container # buildah config --port 80/tcp working-container # buildah commit working-container localhost/myhttpd:latestCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List all images in local storage:
podman images
# podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/myhttpd latest 08da72792f60 2 minutes ago 121 MBCopy to Clipboard Copied! Toggle word wrap Toggle overflow Run the
localhost/myhttpdimage and configure port mappings between the container and the host system:podman run -p 8080:80 -d --name myhttpd 08da72792f60
# podman run -p 8080:80 -d --name myhttpd 08da72792f60Copy to Clipboard Copied! Toggle word wrap Toggle overflow Test the web server:
curl localhost:8080
# curl localhost:8080 Your httpd container from scratch works!Copy to Clipboard Copied! Toggle word wrap Toggle overflow
19.7. Removing images with Buildah Copy linkLink copied to clipboard!
Use the buildah rmi command to remove locally stored container images. You can remove an image by its ID or name.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
List all images on your local system:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Remove the
localhost/myechoimage:buildah rmi localhost/myecho
# buildah rmi localhost/myechoCopy to Clipboard Copied! Toggle word wrap Toggle overflow To remove multiple images:
buildah rmi docker.io/library/mynewecho docker.io/library/myecho2
# buildah rmi docker.io/library/mynewecho docker.io/library/myecho2Copy to Clipboard Copied! Toggle word wrap Toggle overflow To remove all images from your system:
buildah rmi -a
# buildah rmi -aCopy to Clipboard Copied! Toggle word wrap Toggle overflow To remove images that have multiple names (tags) associated with them, add the
-foption to remove them:buildah rmi -f localhost/ubi-micro-httpd
# buildah rmi -f localhost/ubi-micro-httpdCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Ensure that images were removed:
buildah images
# buildah imagesCopy to Clipboard Copied! Toggle word wrap Toggle overflow