Ce contenu n'est pas disponible dans la langue sélectionnée.

Chapter 2. Building and testing RHEL bootc images


You can build, test, and deploy RHEL bootc images by using the same tools and techniques as application containers, such as Podman, Containerfiles, and OpenShift Container Platform. You can converge on a single container-native workflow to manage everything from your applications to the underlying operating system.

You can build and configure Red Hat Enterprise Linux bootc-based images by defining your system specifications in a Containerfile. You can generate customized, reproducible, and scalable container-native operating systems tailored to your specific deployment requirements.

A general Containerfile structure is the following:

FROM registry.redhat.io/rhel10/rhel-bootc:latest

RUN dnf -y install [software] [dependencies] && dnf clean all

ADD [application]
ADD [configuration files]
RUN [config scripts]

The following commands in a Containerfile are ignored when the rhel-10-bootc image is installed to a system:

  • ENTRYPOINT and CMD (OCI: Entrypoint/Cmd): you can set CMD /sbin/init instead.
  • ENV (OCI: Env): change the systemd configuration to configure the global system environment.
  • EXPOSE (OCI: exposedPorts): it is independent of how the system firewall and network function at runtime.
  • USER (OCI: User): configure individual services inside the RHEL bootc to run as unprivileged users instead.

The rhel-10-bootc container image reuses the OCI image format.

  • The rhel-10-bootc container image ignores the container config section (Config) when it is installed to a system.
  • The rhel-10-bootc container image does not ignore the container config section (Config) when you run this image by using container runtimes such as podman or docker.

Red Hat Enterprise Linux supports reproducible container builds by using Podman and Buildah, reducing image changes with consistent inputs over time. This feature decreases data pulled from registries when updating images, which is crucial for supply chain security, reliable software deployment, and effective debugging.

Previously, challenges with tar file creation and escalating container image sizes led to increased storage burdens and unnecessary layer pulls, even when underlying data remained unchanged, hindering faster updates in environments, such as, rhel-bootc and RHEL AI. By using reproducible builds for RHEL containers reduces registry storage, creates smaller update payloads, and enables faster downloads by ensuring image layers remain consistent.

For more information, see Introduction to reproducible container builds

2.3. Building a container image

Build a Red Hat Enterprise Linux container image to encapsulate your operating system configuration and applications in a single artifact. By creating a custom image, you can manage your system lifecycle by using standard container tools and ensures consistent deployments across hybrid infrastructure.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Create a Containerfile:

    FROM registry.redhat.io/rhel10/rhel-bootc:latest
    RUN dnf -y install cloud-init && \
        ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \
        dnf clean all

    This Containerfile example adds the cloud-init tool, so it automatically fetches SSH keys and can run scripts from the infrastructure. The tool gathers configuration and secrets from the instance metadata. For example, you can use this container image for pre-generated AWS or KVM guest systems.

  2. Build the <image> image by using Containerfile in the current directory:

    $ podman build -t quay.io/<namespace>/<image>:<tag> .

Verification

  • List all images:

    $ podman images
    REPOSITORY                                  TAG      IMAGE ID       CREATED              SIZE
    localhost/<image>                           latest   b28cd00741b3   About a minute ago   2.1 GB

2.4. Running a container image

You can run a Red Hat Enterprise Linux container image to run your application or validate your operating system build in an isolated environment. By launching the container, you can verify the system behavior and configurations without modifying the host infrastructure.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  • Run the container by using the podman run command with the appropriate options. For example, to run the container named mybootc based on the quay.io/<namespace>/<image>:<tag> container image:

    $ podman run -it --rm --name mybootc quay.io/<namespace>/<image>:<tag> /bin/bash
    • The -i option creates an interactive session. Without the -i option, the shell opens and then exits.
    • The -t option opens a command-line session. Without the -t option, the shell stays open, but you cannot type anything to the shell.
    • The --rm option removes the quay.io/<namespace>/<image>:<tag> container image after the container exits.

Verification

  • List all running containers:

    $ podman ps
    CONTAINER ID  IMAGE                                    COMMAND          CREATED        STATUS            PORTS   NAMES
    7ccd6001166e  quay.io/<namespace>/<image>:<tag>  /sbin/init  6 seconds ago  Up 5 seconds ago          mybootc

2.5. Overriding the version of bootc images

Red Hat Enterprise Linux (RHEL) base images, Universal Base Images (UBI), and rhel-bootc use version numbers that track only the major operating system version. To define a specific version number for a derived image, you can override this value by adding the version label to your Containerfile.

Prerequisites

  • The container-tools meta-package is installed.

Procedure

  1. Create a Containerfile:

    FROM registry.redhat.io/rhel10/rhel-bootc:latest
    # In this example, the custom operating system has its own
    # version scheme.
    # The operating system major version is copied
    # and a sub-version of it is added, which represents a point-in-time
    # snapshot of the base OS content.
    # This just changes the output of bootc status. A deeper level
    # of customization is available by also changing the contents of /usr/lib/os-release.
    # Define the custom version and release metadata
    LABEL org.opencontainers.image.version=”10.1.1”
  2. Build the <image> image by using Containerfile from the current directory:

    $ podman build -t quay.io/<namespace>/<image>:<tag> .

Verification

  • Verify that the override was applied:

    $ podman inspect <image-name> --format '{{index .Labels "org.opencontainers.image.version"}}'

The deployment image must include only the application and its required runtime, without adding any build tools or unnecessary libraries. To achieve this, use a two-stage Containerfile: one stage for building the artifacts and another for hosting the application.

With multi-stage builds, you use multiple FROM instructions in your Containerfile. Each FROM instruction can use a different base and starts a new stage of the build. You can selectively copy artifacts from one stage to another and exclude everything you do not need in the final image.

Multi-stage builds offer several advantages:

Smaller image size
By separating the build environment from the runtime environment, only the necessary files and dependencies are included in the final image, significantly reducing its size.
Improved security
The attack surface is reduced, leading to a more secure container because the build tools and unnecessary libraries are excluded from the final image.
Optimized performance
A smaller image size means faster download, deployment, and startup times, improving the overall efficiency of the containerized application.
Simplified maintenance
With the build and runtime environments separated, the final image is cleaner and easier to maintain, containing only what is needed to run the application.
Cleaner builds
Multi-stage builds help avoid clutter from intermediate files, which could accumulate during the build process, ensuring that only essential artifacts make it into the final image.
Resource efficiency
The ability to build in one stage and discard unnecessary parts minimizes the use of storage and bandwidth during deployment.
Better layer caching
With defined stages, Podman can efficiently cache the results of previous stages, potentially speeding up future builds.

The following Containerfile consists of two stages. The first stage is typically named builder and it compiles a golang binary. The second stage copies the binary from the first stage. The default working directory for the go-toolset builder is opt/ap-root/src.

FROM registry.access.redhat.com/ubi10/go-toolset:latest as builder
RUN echo 'package main; import "fmt"; func main() { fmt.Println("hello world") }' > helloworld.go
RUN go build helloworld.go

FROM registry.redhat.io/rhel10/rhel-bootc:latest
COPY --from=builder /opt/app-root/src/helloworld /
CMD ["/helloworld"]

As a result, the final container image includes the helloworld binary but no data from the previous stage.

You can also use multi-stage builds to perform the following scenarios:

Stopping at a specific build stage
When you build your image, you can stop at a specified build stage. For example:
$ podman build --target build -t hello .

For example, you can use this approach to debug a specific build stage.

Using an external image as a stage
You can use the COPY --from instruction to copy from a separate image. You can use the local image name, a tag available locally or on a container registry, or a tag ID. For example:
COPY --from=<image> <source_path> <destination_path>
Using a previous stage as a new stage
You can continue where a previous stage ended by using the FROM instruction. For example:
FROM ubi10 AS stage1
[...]

FROM stage1 AS stage2
[...]

FROM ubi10 AS final-stage
[...]

2.7. Pushing a container image to the registry

Push your Red Hat Enterprise Linux container image to a remote registry to make it accessible for deployment. By uploading the image, you can distribute your customized operating system across your infrastructure or share it with collaborators for testing.

Prerequisites

  • The container-tools meta-package is installed.
  • An image is built and available on the local system.
  • You have created the Red Hat Quay registry. For more information, see Proof of Concept - Deploying Red Hat Quay.

Procedure

  • Push the quay.io/<namespace>/<image>:<tag> container image from your local storage to the registry:

    $ podman push quay.io/<namespace>/<image>:<tag>

    For more information, see the podman-tag(1) and podman-push(1) man pages on your system.

Red Hat logoGithubredditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance. Découvrez nos récentes mises à jour.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez le Blog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

Theme

© 2026 Red Hat
Retour au début