Lab: Prepare to Build and Deploy Bootc Container Images
Estimated reading time: 6 minutes.
- Objective
-
Prepare for air-gapped building of bootc container images and disconnected deployment of edge devices.
Before you Begin
You need a development machine running Red Hat Enterprise Liunux (RHEL), to which you have unrestricted sudo rights, and access to RHEL package repositories. That machine must have plenty of disk space to store multiple container images and multiple virtual machine (VM) images.
These instructions were tested on RHEL 10.0 but should work with minimal or no changes on newer and older RHEL releases, since 9.6.
If you are using the course classroom, log in on the workstation
VM as the user student
with password student
.
If not, please adapt the instructions to your test environment.
Instructions
You will verify that you have access to mirrors of RHEL package repositories and bootc container images from RHEL. You will also configure your development machine with RHEL virtualization tools, based on libvirt, to perform system testing of your bootc container images.
As a bonus, you will verify that bootc container images have, by convention, a label key that differentiates them from application container images.
-
Verify that your development machine has access to the RHEL package repositories from a DNF mirror.
-
List the configured package repositories. They should match the standard RHEL package repositories.
$ dnf repolist rhel-10.0-for-x86_64-appstream-rpms Red Hat Enterprise Linux 10.0 AppStream (dvd) rhel-10.0-for-x86_64-baseos-rpms Red Hat Enterprise Linux 10.0 BaseOS (dvd)
-
Verify that your RHEL package repositories do NOT point to the Red Hat customer portal. Instead they should point to a machine inside your virtual labs environment.
$ dnf repoinfo rhel-10.0-for-x86_64-baseos-rpms | grep baseurl Last metadata expiration check: 0:01:12 ago on Thu Aug 7 12:48:44 2025. Repo-baseurl : http://content.example.com/rhel10.0/x86_64/dvd/BaseOS
-
Verify that the
bootc
package is available, but do NOT install it.$ dnf info bootc Last metadata expiration check: 0:44:11 ago on Thu Aug 7 12:48:44 2025. Available Packages Name : bootc Version : 1.1.6 Release : 2.el10_0 Architecture : x86_64 Size : 2.7 M Source : bootc-1.1.6-2.el10_0.src.rpm Repository : rhel-10.0-for-x86_64-appstream-rpms Summary : Bootable container system URL : https://github.com/containers/bootc License : Apache-2.0 AND BSD-3-Clause AND MIT AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT) AND (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT) AND (Unlicense OR MIT) Description : Bootable container system
-
-
Install the container tools on your development machine.
You already have Podman installed, but during this course you will use additional convenience tools, such as Skopeo.
$ sudo dnf install skopeo buildah ... Complete!
-
Verify that your development machine has access to bootc base images from a private registry.
-
The private registry requires authentication, even for images that would be public on the Red Hat registries.
$ podman login -u student -p redhat registry.lab.example.com:5000 Login Succeeded!
-
List all images available on the private registry. The list should include some application container images and some bootc container images, for different releases of RHEL.
$ podman search registry.lab.example.com:5000/ NAME DESCRIPTION registry.lab.example.com:5000/openshift4/microshift-bootc-rhel9 registry.lab.example.com:5000/rhel10/bootc-image-builder registry.lab.example.com:5000/rhel10/rhel-bootc registry.lab.example.com:5000/rhel9-eus/rhel-9.6-bootc registry.lab.example.com:5000/rhel9-eus/rhel-9.6-bootc-image-builder registry.lab.example.com:5000/ubi10/ubi registry.lab.example.com:5000/ubi9/ubi
The podman search
command, and similar commands from other tools such as Docker, are not reliable to list container images in a production container registry nor to verify the availability of an image by its name and tag. Container registry servers do NOT have to return the results in any strict order. They can truncate the results, and do NOT have to return any indication that the results were truncated. Thepodman search
command works here only because there is a small number of container images stored in the private registry. -
Inspect the RHEL 10 base bootc image to verify it is indeed a bootc container image. Look for the
containers.bootc
key.Instead of displaying all information about a container, which could spawn multiple pages of your terminal, use the
--format
option to list only the labels,$ skopeo inspect --format '{{ .Labels }}' docker://registry.lab.example.com:5000/rhel10/rhel-bootc map[architecture:x86_64 build-date:2025-07-31T04:03:30 com.redhat.component:rhel-bootc-component containers.bootc:1 description:RHEL bootc container distribution-scope:public io.buildah.version:1.40.1 io.k8s.description:RHEL bootc container name:rhel10/rhel-bootc org.opencontainers.image.source:https://gitlab.com/redhat/rhel/bifrost/rhel-bootc.git ostree.bootable:1 ostree.commit:8f3b22bd5d278d525440baa3ae7709fa89d575d7f6799f82913c805f2d7b8b1e ostree.final-diffid:sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1 redhat.compose-id: redhat.id:rhel redhat.version-id:10.0 release:10.0 url:https://www.redhat.com vcs-ref:2ff3f1d1ffe1b320f7a54ef32c4fd19551736eba vcs-type:git vendor:Red Hat, Inc. version:10.0]
-
You can output the information in JSON format and format it for legibility, which makes it easier to visually find a specific key.
$ skopeo inspect --format '{{ json .Labels }}' docker://registry.lab.example.com:5000/rhel10/rhel-bootc | jq { "architecture": "x86_64", "build-date": "2025-07-31T04:03:30", "com.redhat.component": "rhel-bootc-component", "containers.bootc": "1",(1) "description": "RHEL bootc container", "distribution-scope": "public", "io.buildah.version": "1.40.1", "io.k8s.description": "RHEL bootc container", "name": "rhel10/rhel-bootc", "org.opencontainers.image.source": "https://gitlab.com/redhat/rhel/bifrost/rhel-bootc.git", "ostree.bootable": "1", "ostree.commit": "8f3b22bd5d278d525440baa3ae7709fa89d575d7f6799f82913c805f2d7b8b1e", "ostree.final-diffid": "sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1", "redhat.compose-id": "", "redhat.id": "rhel", "redhat.version-id": "10.0", "release": "10.0", "url": "https://www.redhat.com", "vcs-ref": "2ff3f1d1ffe1b320f7a54ef32c4fd19551736eba", "vcs-type": "git", "vendor": "Red Hat, Inc.", "version": "10.0" }
1 The label could take any value, but by convention it should be set to "1" or empty. -
Alternatively, you can check for the
containers.bootc
key directly, without using JSON or thejq
command.$ skopeo inspect --format '{{ index .Labels "containers.bootc" }}' docker://registry.lab.example.com:5000/rhel10/rhel-bootc 1
-
Verify that an application container image, for example a UBI base image, does NOT have a
containers.bootc
label.$ skopeo inspect --format '{{ index .Labels "containers.bootc" }}' docker://registry.lab.example.com:5000/ubi10/ubi $
Because the output of the last command is empty, you may want to retrieve and format all labels, just to be sure.
-
-
Explore the contents of a bootc container image and an application container image and notice important packages that are present or not.
-
Bootc container images include the bootable container system utility, that is, the
bootc
package and the command with the same name.$ podman run --rm --name bootc registry.lab.example.com:5000/rhel10/rhel-bootc bash -c "rpm -q bootc" ... bootc-1.1.6-2.el10_0.x86_64 $ podman run --rm --name ubi registry.lab.example.com:5000/ubi10/ubi bash -c "rpm -q bootc" .. package bootc is not installed
Be patient, bootc container images are considerably larger than regular application containers, so they take longer to download. -
Bootc container images include a Linux kernel.
$ podman run --rm --name bootc registry.lab.example.com:5000/rhel10/rhel-bootc bash -c "rpm -q kernel" ... kernel-6.12.0-55.24.1.el10_0.x86_64 $ podman run --rm --name ubi registry.lab.example.com:5000/ubi10/ubi bash -c "rpm -q kernel" .. package kernel is not installed
-
-
Install the RHEL virtualization tools.
-
Install the Libvirt tools and enable the Libvirt socket.
$ sudo dnf install qemu-kvm libvirt virt-install virt-viewer ... Complete! $ sudo systemctl enable virtqemud.socket --now Created symlink /etc/systemd/system/multi-user.target.wants/virtqemud.socket → /usr/lib/systemd/system/virtqemud.socket.
-
Check that your unprivileged user can connect to Libvirt’s session interface.
$ virsh uri qemu:///session $ virsh nodeinfo CPU model: x86_64 ...
-