Chapter 6. Creating bootc-compatible base disk images by using bootc-image-builder
Create disk images from bootc images by using the bootc-image-builder tool. These artifacts help you to provision your containerized operating system across diverse infrastructure, including physical hardware, virtual machines, edge and cloud environments.
6.1. About image mode for RHEL for bootc-image-builder Copy linkLink copied to clipboard!
You can convert bootc images into disk images for various platforms and formats by using the bootc-image-builder tool. This process is equivalent to installing a bootc image and enables you to update images directly from the container registry after deployment.
You can build your base images by using one of the following methods:
- Use a local RHEL system, install the Podman tool, and build your image locally. Then, you can push the images to your private registry.
Use a CI/CD pipeline: Create a CI/CD pipeline that uses a RHEL-based system to build images and push them to your private registry.
The
bootc-image-buildertool supports generating the following image types:- Disk image formats, such as ISO, that are suitable for disconnected installations.
Virtual disk image formats, such as:
- QEMU copy-on-write (QCOW2)
- Amazon Machine Image (AMI)
- Unformatted raw disk (Raw)
Virtual Machine Image (VMI)
The
bootc-image-buildertool uses the local container storage by default. It cannot pull container images from remote registries itself.To build the disk images, you can make the base bootc container image available in the system’s local container registry. Mount the system’s container storage into the
bootc-image-buildertool so it can use containers from the system storage.Deploying from a container image is beneficial when you run VMs or servers because you can achieve the same installation result. The consistency extends across multiple different image types and platforms when you build them from the same container image.
Consequently, you can minimize the effort in maintaining operating system images across platforms. You can also update systems that you deploy from these disk images by using the
bootctool, instead of re-creating and uploading new disk images withbootc-image-builder.Although you can deploy a
rhel-10-bootcimage directly, you can also create your own customized images that are derived from this bootc image. Thebootc-image-buildertool takes therhel-10-bootcOCI container image as an input.NoteGeneric base container images do not include any default passwords or SSH keys. Also, the disk images that you create by using the
bootc-image-buildertool do not contain the tools that are available in common disk images, such ascloud-init. These disk images are transformed container images only.
6.2. Installing bootc-image-builder Copy linkLink copied to clipboard!
To install the bootc-image-builder, use the Red Hat Container Registry. The bootc-image-builder is intended to be used as a container and it is not available as an RPM package in RHEL.
Prerequisites
-
The
container-toolsmeta-package is installed. The meta-package contains all container tools, such as Podman, Buildah, and Skopeo. -
You are authenticated to
registry.redhat.io. For details, see Red Hat Container Registry Authentication.
Procedure
Log in to authenticate to
registry.redhat.io:$ sudo podman login registry.redhat.ioInstall the
bootc-image-buildertool:$ sudo podman pull registry.redhat.io/rhel10/bootc-image-builder
Verification
List all images pulled to your local system:
$ sudo podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/rhel10/bootc-image-builder latest b361f3e845ea 24 hours ago 676 MB
6.3. Supported image customizations for a configuration file Copy linkLink copied to clipboard!
You can use a build configuration file in the TOML or JSON format to add customizations for your resulting disk image. The container directory maps the configuration file to /config.toml. The customizations object defines the image modifications.
Additionally, you can embed a build configuration file, either as config.json or config.toml in the /usr/lib/bootc-image-builder directory. The system uses these default customizations unless explicitly overridden. For the JSON format, you can also pass the configuration by using stdin when you use the --config argument.
- User customization
Add a user to your disk image, and optionally set an SSH key. All fields for this section are optional except for the
name.Expand TOML JSON [[customizations.user]] name = "user" password = "password" key = "ssh-rsa AAA ... user@email.com" groups = ["wheel"]{ "customizations": { "user": [ { "name": "user", "password": "password", "key": "ssh-rsa AAA ... user@email.com", "groups": [ "wheel", "admins" ] } ] } }- Kernel configuration
You can customize the kernel boot parameters in the configuration file.
Expand TOML JSON [customizations.kernel] name = "kernel-debug" append = "nosmt=force"{ "customizations": { "kernel": { "append": "mitigations=auto,nosmt" } } }- File systems configuration
You can use the file system section of the customizations to set the minimum size of the base partitions, such as
/and/boot, and to create extra partitions with mount points under/var.Expand TOML JSON [[customizations.filesystem]] mountpoint = "/" minsize = "10 GiB" [[customizations.filesystem]] mountpoint = "/var/data" minsize = "20 GiB"{ "customizations": { "filesystem": [ { "mountpoint": "/", "minsize": "10 GiB" }, { "mountpoint": "/var/data", "minsize": "20 GiB" } ] } }- File system type interaction with rootfs
The root file system type (
--rootfs) argument overrides the default value from the source container. It also sets the file system types for all additional mount points for theext4,xfs, andbtrfstypes.For supported mount points and sizes, the following restrictions and rules apply, unless the
rootfsisbtrfs:-
You can specify
/to set the minimum size of the root file system. The final size of the file system, mounted at/sysrooton a booted system, equals the value you specify in this configuration or 2x the size of the base container, whichever is larger. -
You can specify
/bootto set the minimum size of the boot partition. You can also specify subdirectories of/var, but you cannot specify symlinks in/var. For example,/var/homeand/var/runare symlinks and cannot be file systems on their own. -
/varitself cannot be a mount point. Therootfsoption defines the file system type for the root file system. -
Currently, there is no support for creating
btrfssubvolumes during build time. Therefore, if therootfsisbtrfs, no custom mount points are supported under/var. You can only configure/and/boot.
-
You can specify
- Anaconda ISO (installer) configuration options
Create a Kickstart file that contains the installation commands of your choice. Then, add a Kickstart file to your ISO build to create a fully customized and automated installation medium.
NoteThe following combined customizations are not supported:
[customizations.user]and[customizations.installer.kickstart]. When you add a Kickstart, use a configuration file in theTOMLformat, because multi-line strings are prone to error.Expand TOML JSON [customizations.installer.kickstart] contents = """ text --non-interactive zerombr clearpart --all --initlabel --disklabel=gpt autopart --noswap --type=lvm network --bootproto=dhcp --device=link --activate --onboot=on """{ "customizations": { "installer": { "kickstart": { "contents": "text --non-interactive\nzerombr\nclearpart --all --initlabel --disklabel=gpt\nautopart --noswap --type=lvm\nnetwork --bootproto=dhcp --device=link --activate --onboot=on" } } } }WarningThe
bootc-image-builderdoes not add additional Kickstart commands besides the container image, which the system adds automatically to the container image. See Creating Kickstart files for more information.
6.4. Creating QEMU disk images by using bootc-image-builder Copy linkLink copied to clipboard!
To prepare a pre-configured RHEL image that is bootable with the KVM hypervisor, you can build a RHEL bootc image into a QEMU (QCOW2) image. Then, you can run the QCOW2 image in a virtual machine.
Prerequisites
- You have Podman installed on your host machine.
-
You have root access to run the containers in
--privilegedmode. -
You have root or sudo access.
bootc-image-builderrequires rootful Podman to build images. Running it in rootless mode causes the build to fail. - You have the base bootc container image available in the systems root container registry.
Procedure
Optional: Create a
config.tomlfile to prepare a user configuration for the QCOW2 image.The RHEL base image does not include a default user. To add a user configuration, populate the file with content similar to the following:
[[customizations.user]] name = "user" password = "pass" key = "ssh-rsa AAA ... user@email.com" groups = ["wheel"]Later, you can use this file to inject the user configuration when running the
bootc-image-buildercontainer.Alternatively, you can configure the base image by using
cloud-initto inject users and SSH keys on first boot. See Users and groups configuration.Before running the container, you must initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputEnsure that the required image is pulled to the system storage:
$ quay.io/<namespace>/<image>:<tag>The local image can be one of the following:
- An image that you built by using a Containerfile
- An image that you pulled from a private, access-controlled registry that required a login
-
An image that you loaded from a
.tarfile
Run the
bootc-image-buildercontainer. Optionally, if you want to use user access configuration, pass theconfig.tomlas an argument. For example:$ sudo podman run \ --rm \ -it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v /var/lib/containers/storage:/var/lib/containers/storage:Z \ -v ./config.toml:/config.toml:Z \ -v ./output:/output:Z \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type qcow2 \ --config /config.toml \ localhost/<local-image>:latest
Verification
-
Check that the
.qcow2image has been created in the specified output folder.
Next steps
-
You can find the
.qcow2image in the output directory.You can use the image to deploy your image. See Deploying a container image using KVM with a QCOW2 disk image. - You can make updates to the image and push the changes to a registry. See Managing RHEL bootc images.
6.5. Creating VMDK images by using bootc-image-builder Copy linkLink copied to clipboard!
You can use bootc-image-builder to generate a Virtual Machine Disk (VMDK) from a RHEL bootc image to deploy bootable container images as virtual machines on VMware vSphere or Oracle VirtualBox. You can use a registry image directly or mount local storage for a locally built image.
Prerequisites
- You have Podman installed on your host machine.
-
You have authenticated to the Red Hat Registry by using the
podman login registry.redhat.io. -
You have pulled the
rhel10/bootc-image-buildercontainer image.
Procedure
Optional: Create a
Containerfileto customize your base image. For example, to includecloud-initandopen-vm-toolsfor VMware vSphere environments:FROM registry.redhat.io/rhel10/rhel-bootc:latest RUN dnf -y install cloud-init open-vm-tools && \ ln -s /usr/lib/systemd/system/cloud-init.target /usr/lib/systemd/system/default.target.wants/cloud-init.target && \ rm -rf /var/{cache,log} /var/lib/{dnf,rhsm} && \ systemctl enable vmtoolsd.serviceIf you already have a target
bootcimage built locally or in a remote registry, you can skip this and the next step.Build the
bootcimage:$ sudo podman build . -t localhost/rhel-bootc-vmdkOptional: If you want to customize your image configuration, such as adding users or configuring filesystems, create a
config.tomlfile in your current working directory.[[customizations.user]] name = "user" password = "pass" key = "ssh-rsa AAA ... user@email.com" groups = ["wheel"]Before running the container, initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputRun
bootc-image-builderand specify--type vmdkto generate the VMDK disk image from your container image. The image must be accessible from a registry, such asregistry.redhat.io/rhel10/bootc-image-builder:latest.NoteThe
--configoption and volume mount-v ./config.toml:/config.toml:roare only required if you created aconfig.tomlfile. If not, omit the--config /config.tomlline and its corresponding-v ./config.toml:/config.toml:rovolume mount.$ sudo podman run \ --rm \ --privileged \ -v /var/lib/containers/storage:/var/lib/containers/storage \ -v ./output:/output \ -v ./config.toml:/config.toml:ro \ --security-opt label=type:unconfined_t \ --pull newer \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type vmdk \ --config /config.toml \ localhost/rhel-bootc-vmdk:latestA VMDK disk file for the bootc image is stored in the
output/vmdkdirectory.
Next steps
- Deploy your VMDK image to VMware vSphere or VirtualBox.
- Update your bootc container image in the registry to apply updates to deployed instances. See Managing RHEL bootc images.
6.6. Creating GCE images by using bootc-image-builder Copy linkLink copied to clipboard!
Build a RHEL bootc image into a GCE image for the architecture on which you are running the commands.
The RHEL base image does not include a default user. Optionally, you can inject a user configuration by using the --config option to run the bootc-image-builder container. Alternatively, you can configure the base image with cloud-init to inject users and SSH keys on first boot. See Injecting users and SSH keys by using cloud-init.
Prerequisites
- You have Podman installed on your host machine.
-
You have root access to run the
bootc-image-buildertool, and run the containers in--privilegedmode, to build the images.
Procedure
Optional: Create a
config.tomlto configure user access, for example:[[customizations.user]] name = "user" password = "pass" key = "ssh-rsa AAA ... user@email.com" groups = ["wheel"]Before running the container, initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputRun
bootc-image-builder. Optionally, if you want to use user access configuration, pass theconfig.tomlas an argument. The image must be accessible from a registry, such asregistry.redhat.io/rhel10/bootc-image-builder:latest.The following is an example of creating a
gceimage:$ sudo podman run \ --rm \ --it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v ./config.toml:/config.toml \ -v ./output:/output \ -v /var/lib/containers/storage:/var/lib/containers/storage \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type gce \ --config /config.toml \ quay.io/<namespace>/<image>:<tag>You can find the
gceimage in the output directory.
Next steps
- You can make updates to the image and push the changes to a registry. See Managing RHEL bootc images.
Additional resources
6.7. Creating AMI images by using bootc-image-builder and uploading them to AWS Copy linkLink copied to clipboard!
You can use bootc-image-builder to generate an Amazon Machine Image (AMI) from a RHEL bootc image to deploy container-native operating systems as EC2 instances on AWS. For a registry image, mount local storage and for a locally built image, include the -v /var/lib/containers/storage:/var/lib/containers/storage argument.
Prerequisites
- You have Podman installed on your host machine.
-
You have an existing
AWS S3bucket within your AWS account. -
You have root access to run the
bootc-image-buildertool, and run the containers in--privilegedmode, to build the images. -
You have the
vmimportservice role configured on your account to import an AMI into your AWS account.
Procedure
Create a disk image from the bootc image.
- Configure the user details in the Containerfile. Ensure that you assign it with sudo access.
- Build a customized operating system image with the configured user from the Containerfile. It creates a default user without password sudo access.
Optional: Configure the machine image with
cloud-init. See Managing file systems in image mode for RHEL. The following is an example:FROM quay.io/<namespace>/<image>:latest RUN dnf -y install cloud-init && \ ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \ rm -rf /var/{cache,log} /var/lib/{dnf,rhsm}NoteYou can also use
cloud-initto add users and additional configuration by using instance metadata.Build the bootc image. For example, to deploy the image to an
x86_64AWS machine, use the following commands:$ podman build -t quay.io/<namespace>/<image>:<tag> . $ podman push quay.io/<namespace>/<image>:<tag> .Before running the container, initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputUse the
bootc-image-buildertool to create a public AMI image from the bootc container image. The image must be accessible from a registry, such asregistry.redhat.io/rhel10/bootc-image-builder:latest.$ sudo podman run \ --rm \ --it \ --privileged \ --pull=newer \ -v ./config.toml:/config.toml \ -v /var/home/<user>/.aws:/root/.aws \ --env AWS_PROFILE=default \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type ami \ --config /config.toml \ --aws-ami-name rhel-bootc-x86 \ --aws-bucket rhel-bootc-bucket \ --aws-region us-east-1 \ quay.io/<namespace>/<image>:<tag>The following flags must be specified all together. If you do not specify any flag, the AMI is exported to your output directory.
-
--aws-ami-name- The name of the AMI image in AWS -
--aws-bucket- The target S3 bucket name for intermediate storage when you are creating the AMI --aws-region- The target region for AWS uploadsThe
bootc-image-buildertool uses your AWS credentials to build, upload, and register an AMI image to your AWS S3 bucket.
-
Next steps
- You can deploy your image. See Deploying a container image to AWS with an AMI disk image.
- You can make updates to the image and push the changes to a registry. See Managing RHEL bootc images.
Troubleshooting
If you have any issues configuring the requirements for your AWS image, see the following documentation:
Additional resources
6.8. Creating raw disk images by using bootc-image-builder Copy linkLink copied to clipboard!
You can convert a bootc image to a raw image with an MBR or GPT partition table by using the bootc-image-builder.
The RHEL base image does not include a default user. You can inject a user configuration by using the --config option to run the bootc-image-builder container. Alternatively, you can configure the base image with cloud-init to inject users and SSH keys on first boot. See Users and groups configuration - Injecting users and SSH keys by using cloud-init.
Prerequisites
- You have Podman installed on your host machine.
-
You have root access to run the
bootc-image-buildertool, and run the containers in--privilegedmode, to build the images. - You have pulled your target container image in the container storage.
Procedure
Optional: Create a
config.tomlto configure user access, for example:[[customizations.user]] name = "user" password = "pass" key = "ssh-rsa AAA ... user@email.com" groups = ["wheel"]Before running the container, initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputRun
bootc-image-builder. If you want to use user access configuration, pass theconfig.tomlas an argument. The image must be accessible from a registry, such asregistry.redhat.io/rhel10/bootc-image-builder:latest.$ sudo podman run \ --rm \ --it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v /var/lib/containers/storage:/var/lib/containers/storage \ -v ./config.toml:/config.toml \ -v ./output:/output \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type raw \ --config /config.toml \ quay.io/<namespace>/<image>:<tag>You can find the
.rawimage in the output directory.
Next steps
- You can deploy your image. See Deploying a container image by using KVM with a QCOW2 disk image.
- You can make updates to the image and push the changes to a registry. See Managing RHEL bootc images.
6.9. Creating bootable ISOs with Kickstart and partitioning Copy linkLink copied to clipboard!
You can use bootc-image-builder to create an installable ISO image. The anaconda-iso or iso image type creates a bootable installation program that uses the Anaconda installation program to deploy your bootc image to a target system.
By providing a custom Kickstart file in your config.toml, you can define advanced partitioning, such as LVM, custom mount points, or swap space, and automate the installation process.
The creation and deployment of bootable ISO images by using bootc-image-builder is provided as a Technology Preview. This workflow relies on the %ostreecontainer Kickstart command, which is a Technology Preview feature. Technology Preview features are not supported with Red Hat production Service Level Agreements (SLAs), might not be functionally complete, and Red Hat does not recommend using them for production. See Technology Preview Features Support Scope for more information.
Prerequisites
- You have Podman installed on your host machine.
- Your host system is subscribed or you have injected repository configuration by using bind mounts to ensure the image build process can fetch RPMs.
-
You have an image accessible from a registry, such as
registry.redhat.io/rhel10/bootc-image-builder:latest. -
You have root access to run the
bootc-image-buildertool, and run the containers in--privilegedmode, to build the images.
Procedure
Create a
config.tomlto define your custom partitioning, enabling the localization module, and Kickstart instructions.[customizations.installer.kickstart] contents = """ text --non-interactive zerombr clearpart --all --initlabel --disklabel=gpt # Advanced Partitioning part /boot --fstype="xfs" --size=1024 part pv.01 --grow --size=1 volgroup rhel pv.01 logvol / --fstype="xfs" --name=root --vgname=rhel --size=10240 logvol /var --fstype="xfs" --name=var --vgname=rhel --size=5120 logvol swap --name=swap --vgname=rhel --size=2048 network --bootproto=dhcp --device=link --activate --onboot=on reboot """This example defines an LVM-based partitioning scheme with a custom
/varpartition and aswapvolume:Before running the container, initialize the
outputdirectory. Use the-pargument to ensure that the command does not fail if the directory already exists:$ mkdir -p ./outputRun
bootc-image-builderto create the ISO image. Use the--type anaconda-isoflag to ensure the installation program is generated with your Kickstart overrides.$ sudo podman run \ --rm \ --it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v /var/lib/containers/storage:/var/lib/containers/storage \ -v ./config.toml:/config.toml \ -v ./output:/output \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type anaconda-iso \ --config /config.toml \ quay.io/<namespace>/<image>:<tag>
Verification
Verify the output:
$ ls ./output/bootiso/install.isoYou can find the
.anaconda-isoimage in the output directory.
Next steps
You can use the ISO image on unattended installation methods, such as USB sticks or Install-on-boot. The installable boot ISO contains a configured Kickstart file. See Deploying a container image by using Anaconda and Kickstart.
WarningBooting the ISO on a machine with an existing operating system or data can be destructive, because the Kickstart is configured to automatically reformat the first disk on the system.
- You can make updates to the image and push the changes to a registry. See Managing file system in image mode for RHEL bootable.
Additional resources
6.10. Using bootc-image-builder to build ISO images with a Kickstart file Copy linkLink copied to clipboard!
You can create an installable ISO image by using the bootc-image-builder tool. The anaconda-iso or iso image type creates a bootable program that uses the Anaconda installer to deploy your bootc image to a target system.
The creation and deployment of bootable ISO images by using bootc-image-builder is provided as a Technology Preview. This workflow relies on the %ostreecontainer Kickstart command, which is a Technology Preview feature. Technology Preview features are not supported with Red Hat production Service Level Agreements (SLAs), might not be functionally complete, and Red Hat does not recommend using them for production. See Technology Preview Features Support Scope for more information.
Prerequisites
- You have Podman installed on your host machine.
-
You have root access to run the
bootc-image-buildertool, and run the containers in--privilegedmode, to build the images.
Procedure
Create your Kickstart file. The following Kickstart file is an example of a fully unattended Kickstart file configuration that contains user creation, enables the localization module, and partition instructions.
#Enable the Anaconda Localization module on RHEL to enable keyboard or locale changes [customizations.installer.modules] enable = ["org.fedoraproject.Anaconda.Modules.Localization"] [customizations.installer.kickstart] contents = """ lang en_GB.UTF-8 keyboard uk timezone CET user --name <user> --password <password> --plaintext --groups <groups> sshkey --username <user> ssh-<type> <public key> rootpw --lock zerombr clearpart --all --initlabel autopart --type=plain reboot --eject """-
Save the Kickstart configuration in the
tomlformat to inject the Kickstart content. For example,config.toml. Run
bootc-image-builder, and include the Kickstart file configuration that you want to add to the ISO build. Thebootc-image-builderautomatically adds theostreecontainercommand that installs the container image.$ sudo podman run \ --rm \ -it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v /var/lib/containers/storage:/var/lib/containers/storage \ -v ./config.toml:/config.toml \ -v ./output:/output \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type iso \ --config /config.toml \ quay.io/<namespace>/<image>:<tag>You can find the
.isoimage in the output directory.
Next steps
You can use the ISO image on unattended installation methods, such as USB sticks or Install-on-boot. The installable boot ISO contains a configured Kickstart file. The installation program runs automatically based on the
--non-interactiveflag in your Kickstart file, applying the custom LVM partitioning that you defined. See Deploying a container image by using Anaconda and Kickstart.WarningBooting the ISO on a machine with an existing operating system or data can be destructive, because the Kickstart is configured to automatically reformat the first disk on the system.
- You can make updates to the image and push the changes to a registry. See Managing RHEL bootable images.
6.11. Building stateless PXE images with bootc-image-builder Copy linkLink copied to clipboard!
You can use the bootc-image-builder tool to convert a bootc container image into a pxe-tar-xz image type with a set of artifacts, such as kernel, initrd, and squashfs rootfs, that is suitable for network booting.
Prerequisites
- A bootc container.
-
The
dracut-liveandsquashfs-toolspackages are included within your Containerfile. -
The container image is built with the
dmsquash-livemodule built into theinitramfs. See the Containerfile for an example. - A functional TFTP or HTTP server to host the generated artifacts.
Procedure
Create a Containerfile:
FROM quay.io/<namespace>/<image>:latest RUN dnf -y install dracut-live squashfs-tools && dnf clean all # Override using composefs for ostree (it is incompatible with the squashfs rootfs) RUN cat <<EOF > /usr/lib/ostree/prepare-root.conf [composefs] enabled = no [sysroot] readonly = true EOF # Include the dmsquash-live module in the initramfs RUN cat <<EOF > /usr/lib/dracut/dracut.conf.d/40-pxe.conf compress="xz" add_dracutmodules+=" qemu qemu-net livenet dmsquash-live " early_microcode="no" EOF # Rebuild the initrd RUN set -xe; kver=$(ls /usr/lib/modules); env DRACUT_NO_XATTR=1 dracut -vf /usr/lib/modules/$kver/initramfs.img "$kver" # Mask services that aren't compatible with running from the rootfs RUN systemctl mask bootc-generic-growpart.service bootc-publish-rhsm-facts.service RUN bootc container lintBuild the container image:
$ podman build -f ./Containerfile -t bootc-dracutRun
bootc-image-builderto create thetarfile:$ mkdir -p ./output$ sudo podman run \ --rm \ -it \ --privileged \ --pull=newer \ --security-opt label=type:unconfined_t \ -v ./config.toml:/config.toml:ro \ -v ./output:/output \ registry.redhat.io/rhel10/bootc-image-builder:latest \ --type pxe-tar-xz \ --local \ localhost/bootc-dracut:latestIf your Containerfile is on a remote system, replace the
localhost/bootc-dracut:latestwith the correct URL.The resulting
tarfile is the same as for the package-basedpxe-tar-xzimage. The only difference is that thegrub.cfgfile also hasostree=…added to the kernel command line, and therootfs.imgfile is an OSTree system instead of a package-based system.
Verification
Before deploying, verify that the container image was built correctly and contains the necessary configuration files and modules.
Inspect the container you built:
$ podman run --rm -it localhost/bootc-dracut:latest /usr/bin/bash-
Verify that the
/usr/lib/ostree/prepare-root.confand/usr/lib/dracut/dracut.conf.d/40-pxe.conffiles were created correctly. Check initramfs modules to ensure that
dmsquash-liveandostreemodules are present:$ lsinitrd --mod /usr/lib/modules//initramfs.img*
Troubleshooting
- The GRUB menu is not available
- Cause: The EFI binaries or configuration files are misplaced.
-
Resolution: Verify that the
grub.cfgfile is in the same directory as thegrubx64.efifile. Place theBOOTX64.EFI,grubx64.efi, andgrub.cfgfiles at the root of the directory that your TFTP server points to.
- The
rootfs.imgfile fails to load -
Cause:
[FAILED] Failed to start initrd-switch-root.service - Switch Root. -
Resolution: Verify that the initramfs includes the
dmsquash-livemodule. -
Cause:
curlis stuck in a loop trying to download therootfs.imgfile:Warning: failed to download live image: error 253 -
Resolution: Ensure that the
rootfs.imgfile is in the location specified byroot=live:…in thegrub.cfgfile. Check the HTTP server logs to verify that the request path matches the expected location.
-
Cause:
- The OSTree root fails to mount
-
Cause:
ostree-prepare-root: Couldn’t find specified OSTree root -
Resolution: Ensure that the
grub.cfgfile matches therootfs.imgfile, that is, they originate from the sametarfile. Theostree=…entry in thegrub.cfgfile must point to the path in therootfs.imgfile. A mismatch usually occurs when therootfs.imgfile does not match thegrub.cfgfile because the build process sets this UUID from the OSTree directory. -
Cause:
Failed to mount composefs: composefs: failed to mount: Input/output error -
Resolution: Verify that
composefsis disabled in theprepare-root.conffile.
-
Cause:
6.12. Building bootc images in offline and air-gapped environments Copy linkLink copied to clipboard!
You can build bootc container images without connecting to the internet or the Red Hat content delivery network. Use the local mirror registries and the RPM repositories, then convert the container images into VM formats of your choice, such as raw, AMI, or ISO.
Using a disconnected infrastructure requires configuring your build to source container images and RPM content from local registries, for example:
- Private container registries and RPM repositories hosted on private web servers or Red Hat Satellite.
- Pull the base image from a local repository instead of from the internet.
- Your Containerfile must point to a local mirror registry for the base image and use local HTTP servers for RPM content.
After using the bootc-image-builder command to transform the container into a disk image, you can deploy bootable RHEL-based systems in an air-gapped environment.
Define repository configurations inside the container image you are building. You cannot use the host machine’s repository settings with bootc-image-builder. Instead, you must provide the repository configurations directly within the container image.
Prerequisites
- A running RHEL system with Red Hat Enterprise Linux 10 deployed on the target hardware.
-
The
container-toolsmeta-package is installed. - Access to a registry or a locally stored container.
Procedure
Create a Containerfile. For example:
# Base image to point to your internal registry FROM example.com:1234/rhel10/rhel-bootc:10.2 # Configure the local repo to use the files already present in the image # Assuming the repo data is located at /etc/pki/repos or similar inside the image RUN echo -e "[local-baseos]\n\ name=Local RHEL 10 BaseOS\n\ baseurl=file:///path/to/repo/in/image/BaseOS\n\ enabled=1\n\ gpgcheck=0" > /etc/yum.repos.d/local.repo # Install your required packages using the local file source RUN dnf install -y firewalld && \ dnf clean all # Ensure the kernel and bootloader are present # In air-gapped bootc, BIB often fails because it expects to download these. # Pre-installing them ensures they are part of the 'bootc' transition. RUN dnf install -y kernel-bootc anaconda-dracut-modules && dnf clean all-
Use the
bootc-image-buildertool to transform the Containerfile into a bootable format, such as ISO,raw, QCOW2. See Creating bootc-compatible base disk images by using bootc-image-builder.
Troubleshooting
The raw disk images might succeed if the packages are already cached. If you build an ISO, it might trigger the osbuild-depsolve-dnf dependency solving process.
If your .repo files contain a gpgkey URL, bootc-image-builder tool attempts to fetch the gpg key during the manifest generation phase. In an air-gapped environment, check the following information:
-
Ensure the
gpgkeyparameter points to a reachable local HTTP server or a file path already present in the image, such as/etc/pki/rpm-gpg/. -
Even if the
dnf installcommand worked during the container build, because the key was already cached or skipped, the ISO creation process can re-validate these keys. An incorrect URL results in errors such asGPGKeyReadErroror404 Not Found. -
To solve these issues, store GPG Keys locally: Instead of referencing remote URLs for GPG keys, include the keys in your container image and reference them by
file:/in your.repofiles. -
If you encounter a
cannot build manifesterror, double-check that every repository URL and GPG URL inside the container’s/etc/yum.repos.d/are reachable from the network on whichbootc-image-builderis running.
Next steps
- You can deploy your image. See Deploying an image mode update in offline and air-gapped environments.