Search

Chapter 19. Building container images with Buildah

download PDF

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

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 scratch command. 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 the buildah mount and buildah copy commands. 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 commit command. Optionally, you can push the newly created container image to a container registry by using the buildah push command. 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 Containerfile by using the buildah build or buildah bud commands. 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, and dnf. 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 Containerfile as in a Dockerfile.
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

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 run command runs a container. The buildah run command is similar to the RUN directive in a Containerfile.
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.
Note

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

Additional resources

Install the Buildah tool using the yum command.

Procedure

  • Install the Buildah tool:

    # yum -y install buildah

Verification

  • Display the help message:

    # buildah -h

19.4. Getting images with Buildah

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-tools module is installed.

Procedure

  • Create a new working container based on the registry.redhat.io/ubi8/ubi image:

    # buildah from registry.access.redhat.com/ubi8/ubi
    Getting image source signatures
    Copying blob…
    Writing manifest to image destination
    Storing signatures
    ubi-working-container

Verification

  1. List all images in local storage:

    # buildah images
    REPOSITORY                                  TAG      IMAGE ID       CREATED       SIZE
    registry.access.redhat.com/ubi8/ubi         latest   272209ff0ae5   2 weeks ago   234 MB
  2. List the working containers and their base images:

    # buildah containers
    CONTAINER ID  BUILDER  IMAGE ID     IMAGE NAME                       CONTAINER NAME
    01eab9588ae1     *     272209ff0ae5 registry.access.redhat.com/ub... ubi-working-container

Additional resources

  • The buildah-from, buildah-images, and buildah-containers man pages on your system

19.5. Building an image from a Containerfile with Buildah

Use the buildah bud command to build an image using instructions from a Containerfile.

Note

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-tools module is installed.

Procedure

  1. Create a Containerfile:

    # cat Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    ADD myecho /usr/local/bin
    ENTRYPOINT "/usr/local/bin/myecho"
  2. Create a myecho script:

    # cat myecho
    echo "This container works!"
  3. Change the access permissions of myecho script:

    # chmod 755 myecho
  4. Build the myecho image using Containerfile in the current directory:

    # buildah bud -t myecho .
    STEP 1: FROM registry.access.redhat.com/ubi8/ubi
    STEP 2: ADD myecho /usr/local/bin
    STEP 3: ENTRYPOINT "/usr/local/bin/myecho"
    STEP 4: COMMIT myecho
    ...
    Storing signatures

Verification

  1. List all images:

    # buildah images
    REPOSITORY                                  TAG      IMAGE ID       CREATED              SIZE
    localhost/myecho                            latest   b28cd00741b3   About a minute ago   234 MB
  2. Run the myecho container based on the localhost/myecho image:

    # podman run --name=myecho localhost/myecho
    This container works!
  3. List all containers:

    # podman ps -a
    0d97517428d  localhost/myecho                                     12 seconds ago  Exited (0) 13 seconds ago          myecho
Note

You can use the podman history command to display the information about each layer used in the image.

Additional resources

  • buildah-bud man page on your system

19.6. Creating images from scratch with Buildah

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 yum or rpm.
  • If you add a lot of packages, consider using the standard UBI or minimal UBI images instead of scratch images.

Prerequisites

  • The container-tools module is installed.

Procedure

You can adds a web service httpd to a container and configures it to run.

  1. Create an empty container:

    # buildah from scratch
    working-container
  2. Mount the working-container container and save the mount point path to the scratchmnt variable:

    # scratchmnt=$(buildah mount working-container)
    
    
    # echo $scratchmnt
    /var/lib/containers/storage/overlay/be2eaecf9f74b6acfe4d0017dd5534fde06b2fa8de9ed875691f6ccc791c1836/merged
  3. Initialize an RPM database within the scratch image and add the redhat-release package:

    # yum install -y --releasever=8 --installroot=$scratchmnt redhat-release
  4. Install the httpd service to the scratch directory:

    # yum install -y --setopt=reposdir=/etc/yum.repos.d \
          --installroot=$scratchmnt \
          --setopt=cachedir=/var/cache/dnf httpd
  5. Create the $scratchmnt/var/www/html/index.html file:

    # mkdir -p $scratchmnt/var/www/html
    # echo "Your httpd container from scratch works!" > $scratchmnt/var/www/html/index.html
  6. Configure working-container to run the httpd daemon 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

Verification

  1. List all images in local storage:

    # podman images
    REPOSITORY                                 TAG     IMAGE ID      CREATED         SIZE
    localhost/myhttpd                          latest  08da72792f60  2 minutes ago   121 MB
  2. Run the localhost/myhttpd image and configure port mappings between the container and the host system:

    # podman run -p 8080:80 -d --name myhttpd 08da72792f60
  3. Test the web server:

    # curl localhost:8080
    Your httpd container from scratch works!

Additional resources

  • The buildah-config and buildah-commit man pages on your system

19.7. Removing images with Buildah

Use the buildah rmi command to remove locally stored container images. You can remove an image by its ID or name.

Prerequisites

  • The container-tools module is installed.

Procedure

  1. List all images on your local system:

    # buildah images
    REPOSITORY                                  TAG      IMAGE ID       CREATED          SIZE
    localhost/johndoe/webserver                 latest   dc5fcc610313   46 minutes ago   263 MB
    docker.io/library/mynewecho                 latest   fa2091a7d8b6   17 hours ago     234 MB
    docker.io/library/myecho2                   latest   4547d2c3e436   6 days ago       234 MB
    localhost/myecho                            latest   b28cd00741b3   6 days ago       234 MB
    localhost/ubi-micro-httpd                   latest   c6a7678c4139   12 days ago      152 MB
    registry.access.redhat.com/ubi8/ubi         latest   272209ff0ae5   3 weeks ago      234 MB
  2. Remove the localhost/myecho image:

    # buildah rmi localhost/myecho
    • To remove multiple images:

      # buildah rmi docker.io/library/mynewecho docker.io/library/myecho2
    • To remove all images from your system:

      # buildah rmi -a
    • To remove images that have multiple names (tags) associated with them, add the -f option to remove them:

      # buildah rmi -f localhost/ubi-micro-httpd

Verification

  • Ensure that images were removed:

    # buildah images

Additional resources

  • buildah-rmi man page on your system
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.