<?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>Bootc-Image-Builder – TechBlog about OpenShift/Ansible/Satellite and much more</title><link>https://blog.stderr.at/tags/bootc-image-builder/</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>Thu, 09 Apr 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://blog.stderr.at/tags/bootc-image-builder/index.xml" rel="self" type="application/rss+xml"/><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>