Este conteúdo não está disponível no idioma selecionado.

Chapter 5. Supported image customizations


You can customize your image by adding customizations to your blueprint, such as adding an additional RPM package, enabling a service, or customizing a kernel command line parameter.

You can use several image customizations within blueprints. By using the customizations, you can add packages and groups to the image that are not available in the default packages. To use these options, configure the customizations in the blueprint and import (push) it to the RHEL image builder.

5.1. Selecting a distribution

You can use the distro field to specify the distribution to use when composing your images or solving dependencies in the blueprint.

If you leave the distro field empty, the blueprint uses the host distribution. Use repository overrides to download base system RPMs from a custom mirror instead of the Red Hat Content Delivery Network (CDN). This disables the default repositories, so your custom mirror must contain all necessary packages.

You can build images for older major versions on a newer system. For example, you can use a RHEL 10 host to create RHEL 9 and RHEL 8 images. However, you cannot build images for newer major versions on an older system.

Important

You cannot build an operating system image that differs from the RHEL image builder host. For example, you cannot use a RHEL system to build Fedora or CentOS images.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint with the RHEL distribution to always build the specified RHEL image:

    name = "blueprint_name"
    description = "blueprint_version"
    version = "0.1"
    distro = "different_minor_version"

    For example:

    name = "tmux"
    description = "tmux image with openssh"
    version = "1.2.16"
    distro = "rhel-9.6"

    Replace "different_minor_version" to build a different minor version, for example, if you want to build a RHEL 9.6 image, use distro = "rhel-96". On RHEL 9.5 image, you can build minor versions such as RHEL 9.4, RHEL 9.3, and earlier releases.

5.2. Selecting a package group

Customize the blueprint with package groups. The groups list describes the groups of packages that you want to install into the image.

Package groups are defined in the repository metadata, each group with a descriptive name and an ID. Use the ID to list a group. Groups categorize packages as mandatory, default, or optional. The blueprint installs only mandatory and default packages, and you cannot select optional packages.

The name attribute is a required string and must match exactly the package group ID in the repositories.

Note

Currently, there are no differences between packages and modules. Both are treated as RPM package dependencies.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize your blueprint with a package group:

    [[groups]]
    name = "<group_name>"

    Replace group_name with the name of the group. For example:

    [[groups]]
    name = "anaconda-tools"

5.3. Selecting a package

Customize the blueprint with packages and modules.

  • The name attribute is a required string and can be an exact match, or a filesystem glob that uses * for wildcards, and ? for character matching.
  • The optional version attribute accepts an exact match or a glob pattern using * for wildcards, and ? for character matching. If you do not enter a version, the system uses the latest version in the repositories.

When you use a virtual provider as the package name, the version glob must be *. Consequently, you are not able to freeze the blueprint because the provider expands into multiple packages with their own names and versions.

Note

Currently, there are no differences between packages and modules. RHEL image builder treat both as an RPM package dependencies.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize your blueprint with a package:

    [[packages]]
    name = "<package_name>"

    Replace package_name with the name of the package. For example, the tmux-2.9a and the openssh-server-8.* packages.

    [[packages]]
    name = "tmux"
    version = "2.9a"
    
    [[packages]]
    name = "openssh-server"
    version = "8.*"

5.4. Embedding a container

You can customize your blueprint to embed the latest RHEL container. The containers list contains objects with a source, and optionally, the tls-verify attribute.

The container list entries describe the container images to be embedded into the image.

  • source - Mandatory field. Reference to the container image at a registry. This example uses the registry.access.redhat.com registry. You can specify a tag version. The default tag version is the latest.
  • name - The name of the container in the local registry.
  • tls-verify - Boolean field. The tls-verify boolean field controls the Transport Layer Security. The default value is true.

The embedded containers do not start automatically. To start it, create systemd unit files or quadlets with the file customization.

Prerequisites

  • You have created a blueprint.

Procedure

  • To embed a container from registry.access.redhat.com/ubi10/ubi:latest and a container from your host, add the following customization to your blueprint:

    [[containers]]
    source = "registry.access.redhat.com/ubi10/ubi:latest"
    name = local_name
    tls-verify = true
    
    [[containers]]
    source = "localhost/test:latest"
    local-storage = true

    You can access protected container resources by using a containers-auth.json file. See Container registry credentials.

5.5. Setting the image hostname

The customizations.hostname is an optional string that you can use to configure the final image hostname. This customization is optional, and if you do not set it, the blueprint uses the default hostname.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint to configure the hostname:

    [customizations]
    hostname = "<base_image>"

5.6. Specifying host resources in a blueprint

You can use the URI field to reference files from external sources.

By using the URI field in the blueprint file customization structure, you can reference and source files from external locations. This provides flexible customization of the build system beyond files included directly in the blueprint.

Note that this customization currently only supports file URLs.

Prerequisites

  • You created a blueprint.

Procedure

  • Customize the blueprint with a host resource file:

    [customizations]
    name = "<user_name>"
    description = "<user_description>"
    uri = "<file://hostname/path>"

    Replace "file://hostname/path" with, for example, "file://localhost/etc/fstab".

5.7. Specifying additional users

Add a user to the image, and optionally, set their SSH key. All fields for this section are optional except for the name.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint to add a user to the image:

    [[customizations.user]]
    name = "<user_name>"
    description = "<user_description>"
    password = "<password_hash>"
    key = "<public_ssh_key>"
    home = "/home/<user_name>/"
    shell = "/usr/bin/bash"
    groups = ["users", "wheel"]
    uid = <uid_number>
    gid = <gid_number>
    [[customizations.user]]
    name = "admin"
    description = "Administrator account"
    password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31L..."
    key = "PUBLIC SSH KEY"
    home = "/srv/widget/"
    shell = "/usr/bin/bash"
    groups = ["widget", "users", "wheel"]
    uid = 1200
    gid = 1200
    expiredate = 12345

    The GID is optional and must already exist in the image. Optionally, a package creates it, or the blueprint creates the GID by using the [[customizations.group]] entry.

    Replace password_hash with the actual password hash. To generate the password hash, use a command such as:

    $ python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'

    Replace the other placeholders with suitable values.

    Enter the name value and omit any lines you do not need.

    Repeat this block for every user to include.

5.8. Specifying additional groups

Specify a group for the resulting system image. Both the name and the gid attributes are mandatory.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint with a group:

    [[customizations.group]]
    name = "<group_name>"
    gid = <number>

    Repeat this block for every group to include. For example:

    [[customizations.group]]
    name = "widget"
    gid = 1130

5.9. Setting SSH key for existing users

You can use [[customizations.sshkey]] to set an SSH key for the existing users in the final image. Both user and key attributes are mandatory.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint by setting an SSH key for existing users:

    [[customizations.sshkey]]
    user = "root"
    key = "PUBLIC-SSH-KEY"

    For example:

    [[customizations.sshkey]]
    user = "root"
    key = "SSH key for root"

5.10. Appending a kernel argument

You can append arguments to the boot loader kernel command line. By default, RHEL image builder builds a default kernel into the image. However, you can customize the kernel by configuring it in the blueprint.

Prerequisites

  • You have created a blueprint.

Procedure

  • Append a kernel boot parameter option to the defaults:

    [customizations.kernel]
    append = "<kernel_option>"

    For example:

    [customizations.kernel]
    name = "kernel-debug"
    append = "nosmt=force"

5.11. Building RHEL images by using the real-time kernel

Build a RHEL image by using the real-time kernel (kernel-rt). Override a repository by using .json from the /usr/share/image-builder/repositories/ directory to build an image that selects kernel-rt as the default kernel. Deploy the image to a system and use the real-time kernel features.

Note

The real-time kernel runs on AMD64 and Intel 64 server platforms that are certified to run Red Hat Enterprise Linux.

Prerequisites

  • Your system is registered, and RHEL is attached to a RHEL for Real Time subscription.

Procedure

  1. Create a kernel.json file to include the RT kernel repository:

        {
          "name": "kernel-rt",
          "baseurl": "https://cdn.redhat.com/content/dist/rhel10/10/x86_64/rt/os",
          "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBEr………fg==\n=UZd/\n-----END PGP PUBLIC KEY BLOCK-----\n",
          "rhsm": true,
          "check_gpg": true
        },
  2. Create a blueprint. In the blueprint, add the "[customizations.kernel]" customization. The following is an example that contains the "[customizations.kernel]" in the blueprint:

    name = "rt-kernel-image"
    description = ""
    version = "2.0.0"
    modules = []
    groups = []
    distro = "rhel-10.0"
    [[customizations.user]]
    name = "admin"
    password = "admin"
    groups = ["users", "wheel"]
    [customizations.kernel]
    name = "kernel-rt"
    append = ""
  3. Build your image from the blueprint you created. The following example builds a .qcow2 image:

    # image-builder build qcow2 -- blueprint rt-kernel-image --data-dir kernel.json
  4. Deploy the image that you built to the system where you want to use the real-time kernel features.

Verification

  • After booting a VM from the image, verify that the image correctly selected kernel-rt as the default kernel.

    $ cat /proc/cmdline
    BOOT_IMAGE=(hd0,got3)/vmlinuz-6.12.0-0.el10_0_.x86_64+rt...

5.12. Setting time zone and NTP

You can customize your blueprint to configure the time zone and the Network Time Protocol (NTP).

Both timezone and ntpservers attributes are optional strings. If you do not customize the time zone, the system uses Universal Time Coordinated (UTC). If you do not set NTP servers, the system uses the default distribution.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint with the timezone and the ntpservers you want:

    [customizations.timezone]
    timezone = "TIMEZONE"
    ntpservers = "NTP_SERVER"

    For example:

    [customizations.timezone]
    timezone = "US/Eastern"
    ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
    Note

    Some image types, such as Google Cloud, already have NTP servers set up. You cannot override it because the image requires the NTP servers to boot in the selected environment. However, you can customize the time zone in the blueprint.

5.13. Customizing the locale settings

You can customize the locale settings for your resulting system image. Both language and keyboard attributes are mandatory. The first language you add is the primary language, and the remaining languages are secondary.

Prerequisites

  • You have created a blueprint.

Procedure

  • Set the locale settings:

    [customizations.locale]
    languages = ["<language>"]
    keyboard = "<keyboard>"

    For example:

    [customizations.locale]
    languages = ["en_US.UTF-8"]
    keyboard = "us"
  • List the values supported by the languages:

    $ localectl list-locales
  • List the values supported by the keyboard:

    $ localectl list-keymaps

5.14. Customizing firewall

Set the firewall for the resulting system image. By default, the firewall blocks incoming connections, except for services that you explicitly enabled ports, such as sshd.

If you do not want to use the [customizations.firewall] or [customizations.firewall.services], either remove the attributes or set them to an empty list []. If you only want to use the default firewall setup, you can omit the customization from the blueprint.

Note

The Google template explicitly disables the firewall for their environment. You cannot override this behavior by setting the blueprint.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize the blueprint with the following settings to open other ports and services:

    [customizations.firewall]
    ports = ["<ports>"]

    Where ports is an optional list of strings that contain ports or a range of ports and protocols to open. You can configure the ports by using the port:protocol format, or you can configure the port ranges by using the portA-portB:protocol format. For example:

    [customizations.firewall]
    ports = ["22:tcp", "80:tcp", "imap:tcp", "53:tcp", "53:udp", "30000-32767:tcp", "30000-32767:udp"]

    You can use numeric ports or their names from the /etc/services to enable or disable port lists.

  • Specify which firewall services to enable or disable in the customizations.firewall.service section:

    [customizations.firewall.services]
    enabled = ["<services>"]
    disabled = ["<services>"]
  • You can check the available firewall services:

    $ firewall-cmd --get-services

    For example:

    [customizations.firewall.services]
    enabled = ["ftp", "ntp", "dhcp"]
    disabled = ["telnet"]
    Note

    The services listed in firewall.services are different from the service-names available in the /etc/services file.

5.15. Enabling or disabling services

You can control which services to enable during boot time. Some image types have preset services that you cannot override to ensure the image works correctly.

The [customizations.services] settings add to existing services in image templates but do not replace them.

Prerequisites

  • You have created a blueprint.

Procedure

  • Customize which services to enable during boot time:

    [customizations.services]
    enabled = ["services"]
    disabled = ["services"]

    For example:

    [customizations.services]
    enabled = ["sshd", "cockpit.socket", "httpd"]
    disabled = ["postfix", "telnetd"]

5.16. Kickstart file injection in an ISO image

You can use the [customizations.installer] customization to add your Kickstart file to ISO installers builds, such as image installer, for bare metal deployments.

Warning

Booting the ISO on a machine with an existing operating system or data can be destructive, because it configures the Kickstart to automatically reformat the first disk on the system.

You can choose the following options to add your own Kickstart file:

  • Setting all values during the installation process.
  • Enabling the unattended = true field in the Kickstart, and getting a fully unattended installation with defaults.
  • Injecting your own Kickstart by using the Kickstart field. This results in a fully unattended installation if you specify all required fields. Otherwise, the installation program prompts you for missing fields.

    The Anaconda installer ISO image types support the following blueprint customization:

    [customizations.installer]
    unattended = true
    sudo-nopasswd = ["user", "%wheel"]

    unattended: Creates a Kickstart file that fully automates the installation. This includes setting the following options by default:

  • text display mode
  • en_US.UTF-8 language and locale
  • us keyboard layout
  • UTC time zone
  • zerombr, clearpart, and autopart to automatically wipe and partition the first disk
  • network options to enable dhcp and auto-activation

The following is an example:

liveimg --url file:///run/install/repo/liveimg.tar.gz
lang en_US.UTF-8
keyboard us
timezone UTC
zerombr
clearpart --all --initlabel
text
autopart --type=plain --fstype=xfs --nohome
reboot --eject
network --device=link --bootproto=dhcp --onboot=on --activate

sudo-nopasswd: Use to add a Kickstart snippet configured to create /etc/sudoers.d drop-in files, enabling specified users and % prefixed groups to run sudo without a password.

For example, setting the value to ["user", "%wheel"] creates the following Kickstart %post section:

%post
echo -e "user\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/user"
chmod 0440 /etc/sudoers.d/user
echo -e "%wheel\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/%wheel"
chmod 0440 /etc/sudoers.d/%wheel
restorecon -rvF /etc/sudoers.d
%end

As an alternative, you can include a custom Kickstart by using the following customization:

[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
"""

image-builder automatically adds the command that installs the system: liveimg, if it is relevant for the image-installer image type. You cannot use the [customizations.installer.kickstart] customization in combination with any other installer customizations.

5.17. Specifying a partition mode

Use the partitioning_mode variable to select how to partition the disk image that you are building.

You can customize your image with the following supported modes:

  • auto-lvm: It uses the raw partition mode, unless there is one or more filesystem customizations. In that case, it uses the LVM partition mode.
  • lvm: It always uses the LVM partition mode, even when there is no extra mount points.
  • raw: It uses raw partitions even when there are one or more mount points.

Prerequisites

  • You have created a blueprint.

Procedure

  • You can customize your blueprint with the partitioning_mode variable by using the following customization:

    [customizations]
    partitioning_mode = "lvm"

5.18. Custom file system configuration specification

You can specify a custom filesystem configuration in your blueprints and therefore create images with a specific disk layout, instead of the default layout configuration.

By using the non-default layout configuration in your blueprints, you can benefit from:

  • Security benchmark compliance
  • Protection against out-of-disk errors
  • Improved performance
  • Consistency with existing setups
Note

The OSTree systems do not support filesystem customizations, because OSTree images have their own mount rule, such as read-only. The following image types are not supported:

  • image-installer

Additionally, the following image types do not support filesystem customizations, because these image types do not create partitioned operating system images:

  • tar
  • container

For release distributions before 9.4, the blueprint supports the following mountpoints and their sub-directories:

  • / is the root mount point
  • /var
  • /home
  • /opt
  • /srv
  • /usr
  • /app
  • /data
  • /tmp

You cannot specify arbitrary custom mount points on the following mount points and their sub-directories:

  • /bin
  • /boot/efi
  • /dev
  • /etc
  • /lib
  • /lib64
  • /lost+found
  • /proc
  • /run
  • /sbin
  • /sys
  • /sysroot
  • /var/lock
  • /var/run

You can customize the filesystem in the blueprint for the /usr custom mount point, but its subdirectory is not allowed.

If you have more than one partition in the customized image, you can create images with a customized file system partition on LVM and resize those partitions at runtime. To do this, you can specify a customized filesystem configuration in your blueprint and therefore create images with the required disk layout. The default filesystem layout remains unchanged if you use plain images without file system customization, and cloud-init resizes the root partition.

The blueprint automatically converts the file system customization to an LVM partition.

You can use the custom file blueprint customization to create new files or to replace existing files. The parent directory of the file you specify must exist otherwise, the image build fails. Specify the parent directory in the [[customizations.directories]] customization to ensure that it exists.

Warning

Combining file customizations with other blueprint customizations might affect their functioning or override the file customizations.

5.18.1. Custom files specification in the blueprint

With the [[customizations.files]] blueprint customization you can create new text files, or modify existing files. This can override the existing content.

  • Set user and group ownership for the file you are creating.
  • Set the mode permission in the octal format.

You cannot create or replace the following files:

  • /etc/fstab
  • /etc/shadow
  • /etc/passwd
  • /etc/group

You can create customized files and directories in your image by using the [[customizations.files]] and the [[customizations.directories]] blueprint customizations. You can use these customizations only in the /etc directory.

Warning

If you use the customizations.directories with a directory path that already exists in the image with mode, user, or group already set, the image build fails to prevent changing the ownership or permissions of the existing directory.

5.18.2. Custom directories specification in the blueprint

You can use the [[customizations.directories]] blueprint customization to create or modify directories.

With the customization, you can:

  • Create new directories.
  • Set user and group ownership for the directory you are creating.
  • Set the directory mode permission in the octal format.
  • Ensure that parent directories are created as needed.

With the [[customizations.files]] blueprint customization you can:

  • Create new text files.
  • Modify existing files. This can override the existing content.
  • Set user and group ownership for the file you are creating.
  • Set the mode permission in the octal format.
Note

You cannot create or replace the following files:

  • /etc/fstab
  • /etc/shadow
  • /etc/passwd
  • /etc/group

The following customizations are available:

  • Customize the filesystem configuration in your blueprint:

    [[customizations.filesystem]]
    mountpoint = "MOUNTPOINT"
    minsize = MINIMUM-PARTITION-SIZE

    The MINIMUM-PARTITION-SIZE value has no default size format. The blueprint customization supports the following values and units: kB to TB and KiB to TiB. For example, you can define the mount point size in bytes:

    [[customizations.filesystem]]
    mountpoint = "/var"
    minsize = 1073741824
  • Define the mount point size by using units. For example:

    [[customizations.filesystem]]
    mountpoint = "/opt"
    minsize = "20 GiB"
    [[customizations.filesystem]]
    mountpoint = "/var"
    minsize = "1 GiB"
  • Define the minimum partition by setting minsize. For example:

    [[customizations.filesystem]]
    mountpoint = "/var"
    minsize = 2147483648
  • Create customized directories under the /etc directory for your image by using [[customizations.directories]]:

    [[customizations.directories]]
    path = "/etc/directory_name"
    mode = "octal_access_permission"
    user = "user_string_or_integer"
    group = "group_string_or_integer"
    ensure_parents = boolean

    The blueprint entries are described as follows:

    • path Mandatory. Enter the path to the directory that you want to create. It must be an absolute path under the /etc directory.
    • mode Optional. Set the access permission on the directory, in the octal format. If you do not specify a permission, it defaults to 0755. The leading zero is optional.
    • user Optional. Set a user as the owner of the directory. If you do not specify a user, it defaults to root. You can specify the user as a string or as an integer.
    • group Optional. Set a group as the owner of the directory. If you do not specify a group, it defaults to root. You can specify the group as a string or as an integer.
    • ensure_parents Optional. Specify whether you want to create parent directories as needed. If you do not specify a value, it defaults to false.
  • Create a customized file under the /etc directory for your image by using [[customizations.directories]]:

    [[customizations.files]]
    path = "/etc/directory_name"
    mode = "octal_access_permission"
    user = "user_string_or_integer"
    group = "group_string_or_integer"
    data = "Hello world!"

    The blueprint entries are described as follows:

    • path Mandatory. Enter the path to the file that you want to create. It must be an absolute path under the /etc directory.
    • mode Optional. Set the access permission on the file in the octal format. If you do not specify a permission, it defaults to 0644. The leading zero is optional.
    • user Optional. Set a user as the owner of the file. If you do not specify a user, it defaults to root. You can specify the user as a string or as an integer.
    • group Optional. Set a group as the owner of the file. If you do not specify a group, it defaults to root. You can specify the group as a string or as an integer.
    • data Optional. Specify the content of a plain text file. If you do not specify any content, it creates an empty file.

5.19. Volume groups and logical volumes naming specification in the blueprint

You can specify the names of volume groups and logical volumes in the blueprint.

You can use RHEL image builder for the following operations:

  • Create RHEL disk images with an advanced partitioning layout. You can create disk images with custom mount points, LVM-based partitions, and LVM-based SWAP. For example, change the size of the / and the /boot directories by using the config.toml file.
  • Select which file system to use. You can choose between ext4 and xfs.
  • Add swap partitions and LVs. The disk images can contain LV-based SWAP.
  • Change the names of LVM entities. The Logical Volumes (LV) and Volume Groups (VG) inside the images can have custom names.

The following options are not supported:

  • Multiple PVs or VGs in one image.
  • SWAP files
  • Mount options for non-physical partitions, such as /dev/shm, and /tmp.

You can add custom names for VG and LG where the file systems reside, for example:

[[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 = "/home"
label = "home"
fs_type = "ext4"
minsize = "2 GiB"

[[customizations.disk.partitions.logical_volumes]]
name = "swaplv"
fs_type = "swap"
minsize = "1 GiB"
Red Hat logoGithubredditYoutubeTwitter

Aprender

Experimente, compre e venda

Comunidades

Sobre a documentação da Red Hat

Ajudamos os usuários da Red Hat a inovar e atingir seus objetivos com nossos produtos e serviços com conteúdo em que podem confiar. Explore nossas atualizações recentes.

Tornando o open source mais inclusivo

A Red Hat está comprometida em substituir a linguagem problemática em nosso código, documentação e propriedades da web. Para mais detalhes veja o Blog da Red Hat.

Sobre a Red Hat

Fornecemos soluções robustas que facilitam o trabalho das empresas em plataformas e ambientes, desde o data center principal até a borda da rede.

Theme

© 2026 Red Hat
Voltar ao topo