<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>RHEL10 – TechBlog about OpenShift/Ansible/Satellite and much more</title><link>https://blog.stderr.at/tags/rhel10/</link><description>TechBlog about OpenShift/Ansible/Satellite and much more</description><generator>Hugo 0.164.0</generator><language>en-us</language><copyright>Toni Schmidbauer &amp; Thomas Jungbauer</copyright><lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://blog.stderr.at/tags/rhel10/index.xml" rel="self" type="application/rss+xml"/><item><title>Creating a customized RHEL 10 VM image with image-builder</title><link>https://blog.stderr.at/other/2026-04-10-customize-rhel-image-builder/</link><guid isPermaLink="true">https://blog.stderr.at/other/2026-04-10-customize-rhel-image-builder/</guid><pubDate>Fri, 10 Apr 2026 00:00:00 +0200</pubDate><dc:creator>Articles by Toni Schmidbauer</dc:creator><category>Other</category><category>Virtualization</category><description>Creating a customized RHEL 10 VM image with image-builder</description><content:encoded><![CDATA[<div class="paragraph">
<p>In the blog post
<a href="https://blog.stderr.at/other/2026-04-09-macos-rhel10-bootc/">Creating a
RHEL 10 VM on macOS with bootc-image-builder</a> we described how to
quickly create a bootc (<a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/introducing-image-mode-for-rhel">image mode</a>) base image on macOS. Now we would like to
create a customized standard RHEL image.</p>
</div>
<div class="paragraph">
<p>For this exercise we re-use an already provisioned RHEL 10.1 machine, the reasons for this are</p>
</div>
<div class="ulist">
<ul>
<li>
<p>We are going to use the <em>image-builder</em> command instead of <em>bootc
image builder</em>. If there is a container image providing this
command, please let us know</p>
</li>
<li>
<p>We are going to install packages which requires a subscribed RHEL
machine. A RHEL subscription for up to 16 machines is free of charge. You
just need to register at the <a href="https://developers.redhat.com/" rel="noopener" target="_blank">Red Hat developer</a> site.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>First we need to install required tools onto our RHEL 10.1 host:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ sudo dnf install -y image-builder</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next we create a blueprint file to customize the resulting qcow2
image. We use the resulting image for a &#34;services&#34; machine, running
Unifi OS, Kea for DHCP and ISC bind (dns server):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-toml hljs" data-lang="toml">name = &#34;services-rhel10&#34;
description = &#34;A VM running services&#34;
version = &#34;0.1&#34;

[[packages]]
name = &#34;podman&#34;
version = &#34;*&#34; <i class="conum" data-value="1"></i><b>(1)</b>

[customizations]
hostname = &#34;services&#34;

[[customizations.filesystem]]
mountpoint = &#34;/&#34;
minsize = &#34;50 GiB&#34; <i class="conum" data-value="2"></i><b>(2)</b>

[customizations.kernel]
append = &#34;ip=10.0.0.144::10.0.0.1:255.255.255.0:services:ens3:none:10.0.0.255&#34; <i class="conum" data-value="3"></i><b>(3)</b>

[[customizations.group]]
name = &#34;pinhead&#34;
gid = 1000

[[customizations.user]]
name = &#34;pinhead&#34;
password = &#34;&lt;password hash&gt;&#34; <i class="conum" data-value="4"></i><b>(4)</b>
key = &#34;&lt;ssh public key&gt;&#34; <i class="conum" data-value="5"></i><b>(5)</b>
home = &#34;/home/pinhead/&#34;
shell = &#34;/usr/bin/bash&#34;
groups = [&#34;users&#34;, &#34;wheel&#34;]
uid = 1000
gid = 1000

[[customizations.sshkey]]
user = &#34;root&#34;
key = &#34;&lt;public key&gt;&#34; <i class="conum" data-value="6"></i><b>(6)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody><tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>use the latest version of this package</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>resize the resulting image to 50GB</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>we configure a static ip address for this machine, our default interface is <em>ens3</em></td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Enter the generated password hash here (see below)</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>SSH public key to access this account</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b>6</b></td>
<td>SSH public key to access the root account</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>To create a password hash use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">python3 -c &#39;import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass(&#34;Confirm: &#34;)) else exit())&#39;</code></pre>
</div>
</div>
<div class="paragraph">
<p>For a detailed list of all customizations supported by <em>image-builder</em>
see the
<a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/composing_a_customized_rhel_system_image/supported-image-customizations" rel="noopener" target="_blank">image builder customizations</a>
documentation.</p>
</div>
<div class="paragraph">
<p>As mentioned in the
<a href="https://blog.stderr.at/other/2026-04-09-macos-rhel10-bootc/" rel="noopener" target="_blank">previous article</a>
image builder provides the option to configure the resulting
image via kickstart. A builder for kickstart files is available here:</p>
</div>
<div class="paragraph">
<p><a class="bare" href="https://access.redhat.com/labs/kickstartconfig/">https://access.redhat.com/labs/kickstartconfig/</a></p>
</div>
<div class="paragraph">
<p>For a complete list of options see the <a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/automatically_installing_rhel/kickstart-commands-and-options-reference" rel="noopener" target="_blank">kickstart documentation</a>.</p>
</div>
<div class="paragraph">
<p>One important note from the documentation (quoted):</p>
</div>
<div class="admonitionblock note">
<table>
<tbody><tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The following combined customizations are not supported: [customizations.user] and [customizations.installer.kickstart]. When you add a Kickstart, use a configuration file in the TOML format, because multi-line strings are prone to error.
</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>Now we are ready to run <em>image-builder</em>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">image-builder build qcow2 --distro rhel-10.1 --arch x86_64 --blueprint services-blueprint.toml</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command above failed for us with the following error message:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-console hljs" data-lang="console">Failed to open file &#34;/sys/fs/selinux/checkreqprot&#34;: Read-only file system
imported gpg key
Signature check failed on sha256:9d0a71d87912a815f837f8427438936d6e9842834cc1f1062b90b2a41fbde594, lookup package name in manifest.
Traceback (most recent call last):
  File &#34;/run/osbuild/bin/org.osbuild.rpm&#34;, line 260, in &lt;module&gt;
r = main(args[&#34;tree&#34;], args[&#34;inputs&#34;], args[&#34;options&#34;])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &#34;/run/osbuild/bin/org.osbuild.rpm&#34;, line 162, in main
subprocess.run([
  File &#34;/usr/lib64/python3.12/subprocess.py&#34;, line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command &#39;[&#39;rpmkeys&#39;, &#39;--root&#39;, &#39;/run/osbuild/tree&#39;, &#39;--checksig&#39;, &#39;sha256:9d0a71d87912a815f837f8427438936d6e9842834cc1f1062b90b2a41fbde594&#39;]&#39; returned non-zero exit status 1.
Finished module org.osbuild.rpm
Finished pipeline build
manifest - failed
Output:
Failed</code></pre>
</div>
</div>
<div class="paragraph">
<p>According to <a href="https://access.redhat.com/solutions/7136467">this
knowledge base article</a> this is a bug in the current (2026-04-10)
version of image builder.</p>
</div>
<div class="paragraph">
<p>You can download an updated JSON file containing the missing RPM GPG
keys from the article. Drop the <em>RHEL-10.1</em> JSON file in a directory
and run <em>image-builder</em> again:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">image-builder --data-dir override/ build qcow2 --distro rhel-10.1 --arch x86_64 --blueprint services-blueprint.toml <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody><tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Use the <em>--data-dir</em> option and specify the folder with the <em>RHEL-10.1.json</em> file.</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>You can find the resulting qcow image in the output directory under
<em>rhel-10.1-qcow2-x86_64/rhel-10.1-qcow2-x86_64.qcow2</em>.</p>
</div>
<div class="paragraph">
<p>A <em>Makefile</em> to streamline image creation can be found
<a href="https://codeberg.org/tosmi/playground/src/branch/master/rhel/image-builder/Makefile" rel="noopener" target="_blank">here</a>.</p>
</div>]]></content:encoded></item><item><title>Creating a RHEL 10 VM on macOS with bootc-image-builder</title><link>https://blog.stderr.at/other/2026-04-09-macos-rhel10-bootc/</link><guid isPermaLink="true">https://blog.stderr.at/other/2026-04-09-macos-rhel10-bootc/</guid><pubDate>Thu, 09 Apr 2026 00:00:00 +0200</pubDate><dc:creator>Articles by Toni Schmidbauer</dc:creator><category>Other</category><category>Virtualization</category><description>Creating a RHEL 10 VM on macOS with bootc-image-builder</description><content:encoded><![CDATA[<div class="paragraph">
<p>Yes, we have Apple machines in our lab because why not. So we needed a
RHEL 10 VM to set up Ansible Automation Platform, which seems to
support AARCH64 and Red Hat Enterprise Linux 10.</p>
</div>
<div class="paragraph">
<p>We need <a href="https://mac.getutm.app/" rel="noopener" target="_blank">UTM</a> installed on our Mac machine,
either
<a href="https://github.com/utmapp/UTM/releases/latest/download/UTM.dmg" rel="noopener" target="_blank">manually</a>,
via <a href="https://formulae.brew.sh/cask/utm" rel="noopener" target="_blank">Homebrew</a> or using a Nix
<a href="https://github.com/tosmi/nixos-config/blob/7faff0ed92d4bbefbef42641497cd2aa49c54b83/macos/fuji/flake.nix#L146" rel="noopener" target="_blank">flake</a>
(in order of increasing coolness).</p>
</div>
<div class="paragraph">
<p>Podman is also required, same rules as above apply:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://podman-desktop.io/" rel="noopener" target="_blank">manual installation</a></p>
</li>
<li>
<p><a href="https://formulae.brew.sh/cask/podman-desktop" rel="noopener" target="_blank">Homebrew</a></p>
</li>
<li>
<p><a href="https://github.com/tosmi/nixos-config/blob/3a6bc775d3164d080390590522956ad5399a34c6/macos/fuji/flake.nix#L147" rel="noopener" target="_blank">flake.nix</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>We followed the
<a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/creating-bootc-compatible-base-disk-images-by-using-bootc-image-builder" rel="noopener" target="_blank">RHEL documentation</a> for creating a bootable qcow image from a bootc
container image.</p>
</div>
<div class="paragraph">
<p>According to the <a href="https://github.com/osbuild/bootc-image-builder?tab=readme-ov-file#-installation" rel="noopener" target="_blank">upstream image builder docs</a>, we need to make sure
that our podman machine runs rootful. Otherwise image builder will not work. So let’s do this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ podman machine stop
$ podman machine set --rootful
$ podman machine start
$ podman machine info</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next we need to pull the <em>bootc-image-builder</em> image:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ podman login registry.redhat.io <i class="conum" data-value="1"></i><b>(1)</b>
$ podman pull registry.redhat.io/rhel10/bootc-image-builder</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody><tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This requires a valid Red Hat account. Registration is free of charge.</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>Then we can pull the RHEL 10 bootc container, as <em>bootc-image-builder</em> is not able to pull container images:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">podman pull registry.redhat.io/rhel10/rhel-bootc:latest</code></pre>
</div>
</div>
<div class="paragraph">
<p>Image builder provides the option to configure the resulting image via
kickstart. A builder for kickstart files is available here:</p>
</div>
<div class="paragraph">
<p><a class="bare" href="https://access.redhat.com/labs/kickstartconfig/">https://access.redhat.com/labs/kickstartconfig/</a></p>
</div>
<div class="paragraph">
<p>For a complete list of options see the <a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/automatically_installing_rhel/kickstart-commands-and-options-reference" rel="noopener" target="_blank">kickstart documentation</a>.</p>
</div>
<div class="paragraph">
<p>One important note from the documentation (quoted):</p>
</div>
<div class="admonitionblock note">
<table>
<tbody><tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The following combined customizations are not supported: [customizations.user] and [customizations.installer.kickstart]. When you add a Kickstart, use a configuration file in the TOML format, because multi-line strings are prone to error.
</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>For running the image builder we created a <a href="https://codeberg.org/tosmi/playground/src/branch/master/rhel/bootc/config.toml" rel="noopener" target="_blank"><em>toml</em> config file</a> to configure the final qcow image:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-toml hljs" data-lang="toml">[[customizations.user]]
name = &#34;pinhead&#34;
password = &#34;thepassword&#34;
key = &#34;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYhjnWzsArZVyyTa1E6sDbH06rUGDAhAF3bf3pmeBtm toni@stderr.at&#34;
groups = [&#34;wheel&#34;]

[[customizations.filesystem]]
mountpoint = &#34;/&#34;
minsize = &#34;50 GiB&#34;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we are ready to trigger <em>bootc-image-builder</em>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">podman run \
    --rm \
    --privileged \
    --pull=newer \
    --security-opt label=type:unconfined_t \
    -v /var/lib/containers/storage:/var/lib/containers/storage \ <i class="conum" data-value="1"></i><b>(1)</b>
    -v ./config.toml:/config.toml:ro \
    -v ./output:/output \
    registry.redhat.io/rhel10/bootc-image-builder:latest \
    --type qcow2 \
    --config /config.toml \
  registry.redhat.io/rhel10/rhel-bootc:latest</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody><tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>We had to map this directory into the container, maybe this is required because we run podman in a VM on macOS (podman machine).</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>You can find the resulting qcow image in the output directory under
<em>output/qcow2/disk.qcow2</em>. This image can be used to create a RHEL 10
VM in UTM on macOS.</p>
</div>
<div class="paragraph">
<p>It is also possible to customize the container image which is used as
an input for <em>bootc-image-builder</em>. But this requires a valid RHEL
subscription inside the container. The easiest way to achieve this is
by running bootc-image-builder on an already registered RHEL machine.</p>
</div>
<div class="paragraph">
<p>A <em>Makefile</em> to streamline image creation can be found <a href="https://codeberg.org/tosmi/playground/src/branch/master/rhel/bootc/Makefile" rel="noopener" target="_blank">here</a>.</p>
</div>]]></content:encoded></item></channel></rss>