11 Buildah

Use the Buildah utility to create custom Open Container Initiative compliant container images to use with Podman.

The Buildah utility is functionally similar to Podman in the way that it behaves, but maintains independence from Podman to build Open Container Initiative compliant images. The primary difference between Buildah and Podman is in the way the run command is handled. Because the purpose of Buildah is to build images, the run command behaves the same as a RUN statement within a Containerfile, which is a configuration file that contains the settings to automate the creation of a container image. This difference makes it easy to separate image builds from production level container infrastructure, running in Podman, and to easily process existing Containerfile build instructions.

Use Buildah to pull images from existing registries and to change them to create new images with more specialized functionality. You can use Buildah with an existing Containerfile to create an image, or alternately you can pull an image directly and change it within a container running within the Buildah environment.

Podman and Buildah use the same local image store, which means you can start containers in Podman from images that you have built in Buildah. You can also use images that have been pulled locally by Podman as the base images which you use to build new images using Buildah. While local images are shared, the containers themselves run separately within Buildah and Podman. Podman is unable to access containers running within Buildah and Buildah is unable to access containers running within Podman. This is because the containers that run in Buildah are used precisely to run commands to build a new image.

It might be useful to create a private container registry to store the images you build with Buildah. A private registry can be used to push images the images you create, and pull from other Podman clients that might need to use the images to build containers. For information on creating a registry, see Private Container Registries.

For more information about the Containerfile format and build instructions see the containerfile(5) manual page.

For a complete listing of Buildah commands, use the buildah --help command, or view the buildah(1) manual page.

Note:

Most Buildah operations don't require the use of sudo. We recommend you use Buildah as a standard user. Where privileged access is required, use the buildah unshare command to enter into a privileged Buildah shell. For more information, see the buildah-unshare(1) manual pages.

Creating an Image From a Containerfile

Build a container image from a Containerfile using the buildah build command.

Buildah is designed to work directly with an existing Containerfile and processes the file to build a container image using the buildah build command (which is an alias for the buildah build-using-dockerfile and buildah bud commands). The buildah build command behaves similarly to the docker build command.

You can use the default filenames of Containerfile or Dockerfile to specify container images. If you use a different filename, or a name with a file extension, these aren't recognized unless you include the -f option with the buildah build command.

To find out more about using the buildah commit command, see the buildah-commit(1) manual page.

  1. Create a Containerfile.

    Find or create a Containerfile that specifies the contents of the container image. For example, create a file named Containerfile that contains:

    # This image is based on the latest Oracle Linux 9 image
    FROM container-registry.oracle.com/os/oraclelinux:9
    
    # Install OS updates and the httpd software package
    RUN echo "Updating all Oracle packages"; dnf -y update; dnf -y clean all
    RUN echo "Installing the httpd software package"; dnf -y install httpd && dnf -y clean all
    
    # Expose the default httpd server port 80
    EXPOSE 80
    
    # Run the httpd server
    CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
  2. Build the image from the Containerfile.

    Use the buildah build command to build the Containerfile. Include the --tag option to tag the image. Include the --file option to specify the Container filename if the file doesn't use the default naming, or includes a file extension. For example:

    buildah build --tag myimage .

    The image is built, tagged, and added to the local image list.

  3. Validate the image.

    To confirm that the new image is available, use the buildah images command. For example:

    buildah images

    In this example, the image is in the local Podman storage (used by both Buildah and Podman), and the output looks similar to:

    REPOSITORY                      TAG                IMAGE ID       CREATED          SIZE
    localhost/myimage               latest             761c8f4b4f98   6 minutes ago    279 MB
  4. Verify the image can be started in a container.

    The buildah from command can be used to start a container that uses the image. For example:

    buildah from myimage
  5. Verify the container is started.

    Use the buildah containers command to show the container is running. For example:

    buildah containers 

    The output looks similar to:

    CONTAINER ID  BUILDER  IMAGE ID     IMAGE NAME                       CONTAINER NAME
    076b44920a9a     *     761c8f4b4f98 localhost/myimage:latest         myimage-working-container

Creating a Buildah Container from an Image

Pull an image from a container registry and use it to create a Buildah container.

Buildah can pull images from a container registry using the buildah pull command, in the same way that you would pull an image using Podman. Start a Buildah container from an image with the buildah from command. You can run these commands separately, or combine them.

  1. Pull an image.

    Use the buildah pull command to pull an image from a container registry. For example:

    buildah pull container-registry.oracle.com/os/oraclelinux:9-slim
  2. Start a Buildah container from the image.

    Use the buildah from command to start a Buildah container from an image. For example:

    buildah from oraclelinux:9-slim

    Tip:

    You can combine the buildah pull command with the buildah from command to start a container from an image hosted on a remote registry. For example:

    buildah from container-registry.oracle.com/os/oraclelinux:9-slim
  3. Verify the container is started.

    Use the buildah containers command to show the container is running. For example:

    buildah containers 

    The output looks similar to:

    CONTAINER ID  BUILDER  IMAGE ID     IMAGE NAME                       CONTAINER NAME
    ea27cc0312ba     *     bc1c39bd670d localhost:5000/ol9image:v1       oraclelinux-working-container

Changing an Image

Interact with a Buildah container to install software, add files, and mount the container's volume.

You change images by running them as container instances within Buildah and using the buildah run command. This command functions in the same way as RUN statements in a Containerfile. For example, you can use the buildah run command to run shell commands in the Buildah container, such as installing packages and making OS changes.

You can also use other commands such as buildah copy and buildah mount to interact with Buildah containers.

Many of the examples here assume a Buildah container is already created and running that includes an Oracle Linux 9 image. The command to create this container is:

container=$(buildah from container-registry.oracle.com/os/oraclelinux:9)

The Buildah container name is set as a $container variable to make it easier to try the examples.

Example 11-1 Install a package to the Buildah container

Use the buildah run command to install a software package on a container. This example installs nginx.

buildah run $container dnf -y install nginx

Example 11-2 Run a shell command in a Buildah container

Use the buildah run command to display the Oracle Linux release in a Buildah container.

buildah run $container cat /etc/oracle-release

The output looks similar to:

Oracle Linux Server release 9.6

Example 11-3 Copy a file to a Buildah container

Use the buildah copy command to a copy file to a Buildah container.

Create a file named mytext.txt with some content. For example:

This is some text.

Copy the mytext.txt file to the /tmp directory on the container.

buildah copy $container mytext.txt /tmp 

Use the buildah run command to show the contents of the file using the cat command.

buildah run $container cat /tmp/mytext.txt

The output looks similar to:

This is some text.

Example 11-4 Mounting a Buildah container's volume

You can make file changes inside the working container by mounting its root file system on the local host:

First, you need to enter into the Buildah namespace that has elevated permissions. This uses the overlay driver in rootless mode, and is known as a Buildah unshare session. For more information, see the buildah-unshare(1) manual pages.

buildah unshare

The command line user changes to show the user is now root.

Create a container in the unshare session and mount the container's volume.

container=$(buildah from oraclelinux:9)
mnt=$(buildah mount $container)

You can now interact with the volume mount. For example, install a software package on the container's volume:

dnf install --installroot $mnt httpd

When finished, unmount the container.

buildah unmount $container

Return to the original shell using the exit command.

Committing a Buildah Container to an Image

After completing the changes to a container, use the buildah commit command to generate a new image based on the current status of the Buildah container.

Changes to a Buildah container are temporary until they're committed to an image. You can commit a Buildah image to the local storage so it's immediately available in Podman. Buildah also provides the option to push the image to a container registry, and has options to authenticate with a registry, such as user authentication and certificate validation. You must have write access to a registry, so it might be useful to create a private registry for this purpose. For information on creating and using a private registry, see Private Container Registries.

To permanently store the changes to a Buildah container in an image, use the buildah commit command. To find out more about using the buildah commit command, see the buildah-commit(1) manual page.

Example 11-5 Commit a Buildah image to the local storage

Commit a Buildah container to an image the local storage. Include the --rm option to remove the working container from the Buildah environment at the same time.

buildah commit --rm oraclelinux-working-container myol9:v1

You can confirm the image is created using:

buildah images

The output looks similar to:

REPOSITORY                     TAG                IMAGE ID       CREATED         SIZE
localhost/myol9                v1                 6afd745ed1cf   8 seconds ago   519 MB

Example 11-6 Commit a Buildah image to a private secure registry

Commit a Buildah container and push the image to a private secure registry.

buildah commit --rm oraclelinux-working-container docker://myregistry.example.com:5000/myol9:v1

Committing directly to a registry is the same as performing a local commit and then pushing it to a registry later using the buildah push command.

Verify the image can be pulled using Buildah:

buildah pull myregistry.example.com:5000/myol9:v1

Example 11-7 Commit a Buildah image to a private insecure registry

Commit a Buildah container and push the image to a local insecure registry.

buildah commit --tls-verify=false --rm oraclelinux-working-container docker://localhost:5000/myol9:v1

Verify the image can be pulled using Buildah:

buildah pull --tls-verify=false localhost:5000/myol9:v1

Pushing an Image to a Registry

Use the buildah push command to push container images from the local storage to a container registry.

Buildah and Podman handle images interchangeably, so most of the commands that you use to work with images are replicated across these tools and perform the same operation. For example, the buildah push and podman push commands behave identically. You can use either of these commands to push an image to a container registry where you have write access. You might want to create a private registry to push and share images if you don't already have write access to a registry. For information on creating a registry, see Private Container Registries.

Buildah and Podman can also push images to other formats. This means you can create archive formats that you can share and reuse if you don't have access to a registry. For example, you can create a Docker compatible archive to create an archive file that's similar to using the docker save command. Use the format:

buildah push imagename docker-archive:/path/to/archive-file:image:tag

Change docker-archive in the command to oci-archive to generate an archive that complies with the Open Container Initiative specification.

For more information on the buildah push command, see the buildah-push(1) manual page.

Example 11-8 Push an image to a secure private registry

buildah push ol9image:v1 docker://myregistry.example.com:5000/myol9:v1

Verify the image can be pulled using Buildah:

buildah pull myregistry.example.com:5000/myol9:v1

Example 11-9 Commit an image to a private insecure registry

buildah push --tls-verify=false ol9image:v1 docker://localhost:5000/myol9:v1

Verify the image can be pulled using Buildah:

buildah pull --tls-verify=false localhost:5000/myol9:v1

Example 11-10 Create a Docker compatible archive file

buildah push ol9image:v1 docker-archive:/tmp/ol9image.tar:myol9:v1

An archive file is created in /tmp/ol9image.tar that contains the image.

Removing a Buildah Container

Remove Buildah containers using the buildah rm command. This command doesn't affect Podman containers.

The buildah rm command stops and removes a container from the Buildah container list. It removes the working container and unmounts any volume mounts that might have been set up for it. After the container is removed, any changes you made to the working container are lost and can't be retrieved, unless you created an image of the container before you removed it.

The buildah rm only removes the working container from the Buildah environment. Any containers running under Podman, or any existing images are unaffected.

To find out more about using the buildah rm command, see the buildah-rm(1) manual page.

You can also remove containers as you commit them to an image, by including the --rm option with the buildah commit command to both commit a working container and remove it from the Buildah container list at the same time. See Committing a Buildah Container to an Image.

Example 11-11 Remove a Buildah container

buildah rm oraclelinux-working-container

Example 11-12 Remove all Buildah containers

buildah rm --all

Removing an Image

Remove images using the buildah rmi command. This also removes images in Podman.

The buildah rmi command removes a images from the Buildah and Podman image list. Because images are shared between Podman and Buildah, removing an image with this command also removes it for Podman.

To find out more about using the buildah rmi command, see the buildah-rmi(1) manual page.

Example 11-13 Remove an image

buildah rmi localhost/myimage:latest

Example 11-14 Remove all images

buildah rmi --all

Inspecting an Image or Container

The buildah inspect command prints the metadata and history of an image or container created with Buildah. The output is a JSON array and might be helpful to identify historical changes and other information about the image or container.

To find out more about using the buildah inspect command, see the buildah-inspect(1) manual page.

Example 11-15 Inspect a container

Use the buildah inspect command to inspect a container.

buildah inspect image --type container oraclelinux-working-container

Example 11-16 inspect an image

Use the buildah inspect command to inspect an image.

buildah inspect --type image myol9:v1