Chapter 5. Customizing disk images of RHEL image mode with advanced partitioning


You can use the following methods to customize advanced partitions to allows for granular control over disk and filesystem layouts when building and deploying RHEL systems as container images:

  • Disk customizations
  • Filesystem customizations

However, the two customizations are incompatible with each other. You cannot use both customizations in the same blueprint, which is a text file in TOML format that defines the specifications and configurations for a custom RHEL system image.

5.1. Understanding partitions

The following are the general principles about partitions:

  • The full disk image size is always larger than the size of the sum of the partitions, due to requirements for headers and metadata. Consequently, all sizes are treated as minimum requirements, whether for specific filesystems, partitions, logical volumes, or the image itself.
  • When the partition is automatically added, the partition that contains the root filesystem is always the last in the partition table layout. This is valid for a plain formatted partition, an LVM Volume Group, or a Btrfs partition. For disk customizations, the order that you defined is respected.
  • For the raw partitioning, that is, with no LVM, the partition containing the root filesystem is grown to fill any leftover space on the partition table. Logical Volumes are not grown to fill the space in the Volume Group because they are simple to grow on a live system. Some directories have hard-coded minimum sizes which cannot be overridden. These are 1 GiB for / and 2 GiB for /usr. As a result, if /usr is not on a separate partition, the root filesystem size is at least 3 GiB.

Disk customizations provide a more powerful interface to control the entire partitioning layout of the image.

Allowed mountpoints​

When using bootc-image-builder, only the following directories allow customization:

  • The / (root) directory.
  • Custom directories under /var, but not /var itself.
Not allowed mountpoints​

Under /var, the following mount points do not allow customization:

  • /var/home
  • /var/lock
  • /var/mail
  • /var/mnt
  • /var/roothome
  • /var/run
  • /var/srv
  • /var/usrlocal

5.3. Disk customizations in blueprints

You can define the partition table almost entirely in a blueprint by using disk customizations. Disk customizations have the following structure:

  • Partitions: The top level is a list of partitions.

    • type: Each partition has a type, which can be either plain or lvm. If the type is not set, it defaults to plain. The remaining required and optional properties of the partition depend on the type.

      • plain: A plain partition is a partition with a filesystem. It supports the following properties:

        • fs_type: The filesystem type, which should be one of xfs, ext4, vfat, or swap. Setting it to swap will create a swap partition. The mount point for a swap partition must be empty.
        • minsize: The minimum size of the partition, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the partition in the image might be larger for specific mount points. See Understanding partitions section.
        • mountpoint The mount point for the filesystem. For swap partitions, this must be empty.
        • label: The label for the filesystem (optional).
      • lvm: An lvm partition is a partition with an LVM volume group. Only single persistent volumes (PV) volume groups are supported. It supports the following properties:

        • name: The name of the volume group (optional; if unset, the system generates a name automatically).
        • minsize: The minimum size of the volume group, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the partition and volume group in the image might be larger if the value is smaller than the sum of logical volumes it contains.
        • logical_volumes: One or more logical volumes for the volume group. Each volume group supports the following properties:

          • name: The name of the logical volume (optional; if unset, a name will be generated automatically based on the mount point).
          • minsize: The minimum size of the logical volume, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the logical volume in the image might be larger for specific mount points.
          • label: The label for the filesystem (optional).
          • fs_type: The filesystem type, which should be one of xfs, ext4, vfat, or swap. Setting it to swap will create a swap logical volume. The mount point for a swap logical volume must be empty.
          • mount point: The mount point for the logical volume’s filesystem. For swap logical volumes, this must be empty.
  • Order​:

The order of each element in a list is respected when creating the partition table. The partitions are created in the order they are defined, regardless of their type.

  • Incomplete partition tables​:

Incomplete partitioning descriptions are valid. Partitions, LVM logical volumes, are added automatically to create a valid partition table. The following rules are applied:

  • A root filesystem is added if one is not defined. This is identified by the mount point /. If an LVM volume group is defined, the root filesystem is created as a logical volume, otherwise it will be created as a plain partition with a filesystem. The type of the filesystem, for plain and LVM, depends on the distribution (xfs for RHEL and CentOS, ext4 for Fedora). See Understanding partitions section for information about the sizing and order of the root partition.
  • A boot partition is created if needed and if one is not defined. This is identified by the mountpoint /boot. A boot partition is needed when the root partition (mount point /) is on an LVM logical volume. It is created as the first partition after the ESP (see next item).
  • An EFI system partition (ESP) is created if needed. This is identified by the mount point /boot/efi. An ESP is needed when the image is configured to boot with UEFI. This is defined by the image definition and depends on the image type, the distribution, and the architecture. The type of the filesystem is always vfat. By default, the ESP is 200 MiB and is the first partition after the BIOS boot (see next item).
  • A 1 MiB unformatted BIOS boot partition is created at the start of the partition table if the image is configured to boot with BIOS. This is defined by the image definition and depends on the image type, the distribution, and the architecture. Both a BIOS boot partition and an ESP are created for images that are configured for hybrid boot.
  • Combining partition types​:

You can define multiple partitions. The following combination of partition types are valid:

  • plain and lvm: Plain partitions can be created alongside an LVM volume group. However, only one LVM volume group can be defined.
  • Examples: Blueprint to define two partitions

The following blueprint defines two partitions. The first is a 50 GiB partition with an ext4 filesystem that will be mounted at /data. The second is an LVM volume group with three logical volumes, one for root /, one for /var/home directories, and a swap space in that order. The LVM volume group will have 15 GiB of non-allocated space.

[[customizations.disk.partitions]]
type = "plain"
label = "data"
mountpoint = "/data"
fs_type = "ext4"
minsize = "50 GiB"

[[customizations.disk.partitions]]
type = "lvm"
name = "mainvg"
minsize = "20 GiB"

[[customizations.disk.partitions.logical_volumes]]
name = "rootlv"
mountpoint = "/"
label = "root"
fs_type = "ext4"
minsize = "2 GiB"

[[customizations.disk.partitions.logical_volumes]]
name = "homelv"
mountpoint = "/var/home"
label = "home"
fs_type = "ext4"
minsize = "2 GiB"

[[customizations.disk.partitions.logical_volumes]]
name = "swaplv"
fs_type = "swap"
minsize = "1 GiB"
Copy to Clipboard Toggle word wrap

Filesystem customization provides the final partition table of an image that you built with image builder, and it is determined by a combination of the following factors:

  • The base partition table for a given image type.
  • The relevant blueprint customizations:

    • Partitioning mode.
    • Filesystem customizations.
  • The image size parameter of the build request:

    • On the command line, this is the --size option of the composer-cli compose start command.

The following describes how these factors affect the final layout of the partition table.

  • Modifying partition tables​

You can modify the partition table by taking the following aspects in consideration:

  • Partitioning modes​

The partitioning mode controls how the partition table is modified from the image type’s default layout.

  • The raw partition type does not convert any partition to LVM.
  • The lvm partition type always converts the partition that contains the / root mountpoint to an LVM Volume Group and creates a root Logical Volume. Except from /boot, any extra mountpoint is added to the Volume Group as new Logical Volumes.
  • The auto-lvm mode is the default mode and converts a raw partition table to an LVM-based one if and only if new mountpoints are defined in the filesystems customization. See the Mountpoints entry for more details.

    • Mountpoints

You can define new filesystems and minimum partition sizes by using the filesystems customization in the blueprint. By default, if new mountpoints are created, a partition table is automatically converted to LVM. See the Partitioning modes​ entry for more details.

  • Image size ​ The minimum size of the partition table is the size of the disk image. The final size of the image will either be the value of the size parameter or the sum of all partitions and their associated metadata, depending on which one is the larger.

When you create images with specific sizes in RHEL Image Mode, especially when using bootc and bootc-image-builder, you define the desired disk size within your image build process. While exact sizes can be challenging due to overheads, you can specify minimum requirements.

Prerequisites

  • You must specify the exact [Image size] in the build request.
  • You must specify mountpoints as customizations with sizes smaller than the total size in sum. This is required because the partition table, partitions, and other entities often require extra space for metadata and headers. Thus, the space to fit all mountpoints is always larger than the sum of the partition sizes. However, the exact size of the extra space varies based on many factors, such as image type.

Procedure

The following are steps to create a disk image of a very specific size in the TOML file:

  1. Define the image_size parameter within the [disk] section of your config.toml file:

    [disk]
    image_size = 10737418240 # Example: 10GB in bytes
    Copy to Clipboard Toggle word wrap

Add any extra mountpoints with their required minimum sizes. Ensure that the sum of the sizes is smaller than the image size by at least 3.01 GiB if no /usr mountpoint exists, or at least 1.01 GiB if one does. The extra 0.01 MiB is more than enough for the headers and metadata, for which extra space might be reserved. Do not specify a size for the / mountpoint.

With this, you create a disk with a partition table of the desired size with each partition sized to fit the desired mountpoints. The root partition, root LVM Logical Volume, will be at least 3 GiB, or 1 GiB if /usr is specified. See Understanding partitions for more details.

  • If the partition table does not have any LVM Volume Groups (VG), the root partition will be grown to fill the remaining space.
  • If the partition table contains an LVM Volume Group (VG), the VG will have unallocated extents that can be used to grow any of the Logical Volumes.

You can customize your bootc-image-builder blueprint to implement advanced partitioning for osbuild-composer. The following are possible custom mountpoints:

  • You can create LVM-based images under all partitions on LVs except, /boot and /boot/efi.
  • You can create an LV-based swap.
  • You can give VGs and LVs custom names.

Include partitioning configurations in the base image that bootc-image-builder will read to create the partitioning layout, making the container itself the source of truth for the partition table. Mountpoints for partitions and logical volumes should be created in the base container image used to build the disk. This is particularly important for top-level mountpoints, such as the /app mountpoint. The bootc-image-builder will validate the configuration against the bootc container before building, in order to avoid creating unbootable images.

Prerequisites

  • You have Podman installed on your host machine.
  • You have root access to run the bootc-image-builder tool, and run the containers in --privileged mode, to build the images.
  • QEMU is installed.

Procedure

  1. Create a config.tom file with the following content:

    1. Add a user to the image.

      [[customizations.user]]
      name = "user1"
      password = "user2"
      key = "ssh-rsa AAA ... user@email.com"
      groups = ["wheel"]
      
      # Set a size for the root partition:
      
      [[customizations.partitioning.plain.filesystems]]
      mountpoint = "/"
      type = "ext4"
      minsize = "3 GiB"
      
      # Add an extra data partition
      [[customizations.partitioning.plain.filesystems]]
      mountpoint = "/var/data"
      type = "xfs"
      minsize = "2 GiB"
      label = "data"
      
      
      # Add an app partition with a top-level mountpoint.
      # Requires derived container.
      [[customizations.partitioning.plain.filesystems]]
      mountpoint = "/app"
      type = "xfs"
      minsize = "1 GiB"
      label = "app"
      
      # Add the LVM configuration:
      # Define the LVM Volume Group name and size
      [[customizations.partitioning.lvm.volume_groups]]
      name = "rhelvg"
      minsize = 10737418240  # 10 GiB
      
      
      # Add a data Logical Volume to the group
      [[customizations.partitioning.lvm.volume_groups.logical_volumes]]
      name = "datalv"
      mountpoint = "/var/data"
      label = "data"
      minsize = "1 GiB"
      type = "xfs"
      
      
      # The root Logical Volume is created automatically if not defined, but setting
      # it lets us set the name, label, and size explicitly
      [[customizations.partitioning.lvm.volume_groups.logical_volumes]]
      name = "rootlv"
      mountpoint = "/"
      label = "system"
      minsize = "2 GiB"
      type = "ext4"
      
      
      # Add an app Logical Volume with a top-level mountpoint.
      # Requires derived container.
      [[customizations.partitioning.lvm.volume_groups.logical_volumes]]
      mountpoint = "/app"
      type = "xfs"
      minsize = "1 GiB"
      label = "app"
      name = "applv"
      Copy to Clipboard Toggle word wrap
  2. Run the bootc-image-builder. Optionally, if you want to use user access configuration, pass the config.toml as an argument. The following is an example of creating a public QCOW2 image:

    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/rhel9/bootc-image-builder:latest \
        --type qcow2 \
        --config /config.toml \
      quay.io/<namespace>/<image>:<tag>
    Copy to Clipboard Toggle word wrap

You can find the .qcow2 image in the output folder.

Verification

  1. Run the resulting QCOW2 file on a virtual machine.

    qemu-system-x86_64 \
         -enable-kvm \
         -cpu host \
         -m 8G \
         -bios /usr/share/edk2/ovmf/OVMF_CODE.fd \
         -snapshot \
         -drive file="${path}/output/qcow2/disk.qcow2"
    Copy to Clipboard Toggle word wrap
  2. Access the system in the virtual machine launched with SSH.

    # ssh -i /<path_to_private_ssh-key> <user1>@<ip-address>
    Copy to Clipboard Toggle word wrap

Next steps

You can create image-mode disk images with advanced partitioning by bootc-image-builder. The image-mode disk images you create for RHEL image mode include custom mount points, custom mount options, LVM-based partitions, and LVM-based swap volumes.

With that, you can, for example, change the size of the / and the /boot directories by using a config.toml file. When installing the RHEL image mode on bare metal, you can benefit from all partitioning features available in the Anaconda installer.

Prerequisites

  • You have Podman installed on your host machine.
  • You have virt-install installed on your host machine.
  • You have root access to run the bootc-image-builder tool, and run the containers in --privileged mode, to build the images.

Procedure

  1. Create a config.toml file to configure custom mount options, for example:

    [[customizations.filesystem]]
    mountpoint = "/"
    minsize = "10 GiB"
    
    [[customizations.filesystem]]
    mountpoint = "/var/data"
    minsize = "20 GiB"
    Copy to Clipboard Toggle word wrap
  2. Run bootc-image-builder, passing the config.toml as an argument.

    Note

    If you do not have the container storage mount and --local image options, your image must be public.

    The following is an example of creating a public image:

    $ sudo podman run \
        --rm \
        -it \
        --privileged \
        --pull=newer \
        --security-opt label=type:unconfined_t \
        -v ./config.toml:/config.toml \
        -v ./output:/output \
        registry.redhat.io/rhel9/bootc-image-builder:latest \
        --type <image_type> \
        --config config.toml \
      quay.io/<namespace>/<image>:<tag>
    Copy to Clipboard Toggle word wrap
Back to top
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. Explore our recent updates.

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.

Theme

© 2025 Red Hat