Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Provisioning image mode for Red Hat Enterprise Linux using Red Hat Satellite

Using kickstart and Anaconda with image mode for Red Hat Enterprise Linux

August 6, 2026
Ian Ballou
Related topics:
Linux
Related products:
Image mode for Red Hat Enterprise Linux

    Image mode for Red Hat Enterprise Linux (RHEL) represents a container-native way to build, configure, install, deploy, and manage RHEL. With Red Hat Satellite, systems administrators can manage fleets of image mode machines just like traditional RHEL machines. This tutorial teaches you how to provision image mode machines using Satellite's network and image-based provisioning features.

    Image mode for Red Hat Enterprise Linux provides a method to build a complete system from a single file (also known as a Containerfile). Updates to image mode systems are downloaded and stored on the system before they are applied simultaneously in a single operation. If required, updates can be completely reversed to the previous state, without restoring data from backups.

    There are three image mode RHEL provisioning strategies. This article focuses on using Anaconda to automate installation using existing Satellite provisioning features.

    Image mode and kickstart

    Kickstart scripts automate RHEL installations with Anaconda. In Satellite, kickstart scripts are stored as provisioning templates of the type "provisioning template". By default, Anaconda uses the "kickstart default" template, which performs tasks such as setting the root password, registering the host to the Red Hat CDN, and configuring remote execution SSH keys.

    The combination of Anaconda's support for the ostreecontainer command and Satellite's provisioning template feature means that image mode provisioning is possible without changes to Satellite's code.

    The ostreecontainer kickstart command only requires one argument: A pullable path to a container image. The path format is the same that podman accepts for podman pull:

    ostreecontainer --url satellite.example.com/path/to/container:latest

    With this command in place, Anaconda installs the machine in image mode.

    Image mode provisioning with Anaconda kickstart follows these steps:

    1. A base RHEL operating system boots up and launches Anaconda.
    2. Anaconda executes the kickstart script
    3. The kickstart script installs the image mode container image to disk through ostreecontainer
    4. The kickstart script finishes
    5. The machine reboots in image mode with the contents of the container image

    It is recommended that the major version of Anaconda used to provision the machine matches the major version of Anaconda within the container image.

    Creating an image mode kickstart template in Satellite

    Satellite provisioning templates are embedded Ruby (ERB) files. Administrators can use one provisioning template for different hosts because Ruby variables are injected into the script through ERB tags. To apply this to image mode provisioning, machines can share a template that provides a unique ostreecontainer command by using variables in the kickstart provisioning template.

    The variables that populate provisioning templates come from either the host in Satellite or parameters configured at a higher scope. For example, all hosts in a Satellite host group could provision with the same container image after a parameter linked to an image mode provisioning template is created.

    Because it's not officially compatible with all other kickstart commands, ostreecontainer cannot simply be added to any kickstart file. The documentation for ostreecontainer describes which commands can be used alongside it. For example, at the time of writing, RHEL 9 does not support the repo kickstart command, but the default kickstart template in Satellite uses the repo command to ensure BaseOS and AppStream are both available in the installation environment. To provision image mode with Satellite, you must create a new image mode kickstart template:

    <%#
    kind: provision
    name: Kickstart Default bootc - Trimmed
    model: ProvisioningTemplate
    oses:
    - RedHat
    -%>
    <%
      # Variable setup for post scripts and container URL
      ostreecontainer = host_param('ostreecontainer')
    -%>
    # This kickstart file was rendered from the Foreman provisioning template "<%= @template_name %>".
    lang <%= host_param('lang') || 'en_US.UTF-8' %>
    selinux --<%= host_param('selinux-mode') || 'enforcing' %>
    keyboard <%= host_param('keyboard') || 'us' %>
    <%
    # Network setup is essential for pulling the container and reporting to Foreman
    @host.interfaces.reject{ |iface| iface.bmc? }.sort_by { |iface| (iface.bond? || iface.bridge?) ? 0 : iface.provision? ? 20 : 10 }.each do |iface|
    -%>
    <%= snippet(
          'kickstart_network_interface',
          variables: {
            iface: iface,
            host: @host,
            static: @static,
            static6: @static6
          }
        ) -%>
    <%
    end
    -%>
    # --- Core Installation ---
    # 1. Set the container image as the installation source
    ostreecontainer --url <%= ostreecontainer %>
    # 2. Set the root password to make the system login-able
    rootpw --iscrypted <%= root_pass %>
    # 3. Allow SSH for remote login; assumes firewall is installed in container
    firewall --service=ssh
    # --- Time ---
    timezone --utc <%= host_param('time-zone') || 'UTC' %>
    <% if host_param('ntp-pools') -%>
    <% host_param('ntp-pools').each do |ntppool| -%>
    timesource --ntp-pool <%= ntppool %>
    <% end -%>
    <% elsif host_param('ntp-server') -%>
    timesource --ntp-server <%= host_param('ntp-server') %>
    <% end -%>
    # --- Bootloader and Partitioning ---
    # This assumes you are assigning a partition table in Foreman.
    bootloader --location=mbr --append="<%= host_param('bootloader-append') || 'nofb quiet splash=quiet' %>" <%= grub_pass %>
    <%= @host.diskLayout %>
    # --- Finalize ---
    text
    skipx
    reboot
    # --- Post-Install Scripts ---
    <%#
      This section injects SSH keys for Foreman, registers the system,
      and signals the build is done.
    %>
    %post
    exec < /dev/tty3 > /dev/tty4
    chvt 3
    (
    if [ ! -f /etc/resolv.conf ] || [ ! -s /etc/resolv.conf ]; then
      cat > /etc/resolv.conf << 'RESOLV_EOF'
    <% if @host.domain -%>
    search <%= @host.domain.name %>
    <% end -%>
    <% if @host.subnet -%>
    <% [@host.subnet.dns_primary, @host.subnet.dns_secondary].compact.each do |nameserver| -%>
    nameserver <%= nameserver %>
    <% end -%>
    <% end -%>
    RESOLV_EOF
    fi
    # A debug section in case of DNS issues
    # echo "=== DNS Configuration ==="
    # cat /etc/resolv.conf
    # echo "=== Testing DNS Resolution ==="
    # nslookup cdn.redhat.com || echo "WARNING: Cannot resolve cdn.redhat.com"
    # echo "=========================="
    <%= snippet 'redhat_register' -%>
    <%= snippet('remote_execution_ssh_keys') %>
    touch /tmp/foreman_built
    chvt 1
    ) 2>&1 | tee /root/install.post.log
    %end
    <%#
    The last post section tells Foreman the build is complete.
    %>
    %post --erroronfail --log=/root/install-callhome.post.log
    if test -f /tmp/foreman_built; then
      echo "calling home: build is done!"
      <%= indent(2, skip1: true, skip_content: 'EOF') { snippet('built', :variables => { :endpoint => 'built', :method => 'POST', :body_file => '/root/install.post.log' }) } -%>
    else
      echo "calling home: build failed!"
      <%= indent(2, skip1: true, skip_content: 'EOF') { snippet('built', :variables => { :endpoint => 'failed', :method => 'POST', :body_file => '/root/install.post.log' }) } -%>
    fi
    sync
    %end

    The new kickstart template above is a shortened version of the default Satellite kickstart template. Incompatible commands have been removed. The ostreecontainer command receives an argument called ostreecontainer that can be specified on the host in Satellite or through any higher-scope parameter source (like host group). Foreman remote execution keys and subscription-manager registration are included as well for convenience.

    Use this template as a starting point, and customize it to suit the needs of your environment. To install this new provisioning template:

    1. Decide which Satellite operating system should become associated with the new provisioning template.
      • The chosen operating system will serve as the base system that runs Anaconda. After the machine is provisioned, it reports the correct operating system that matches the container image back to Satellite.
      • An operating system in Satellite can use one provisioning template of a certain type at a time. If you need to provision package mode and image mode machines of the same OS version, consider creating a new Satellite operating system just for image mode machines.
    2. Navigate to Hosts > Templates > Provisioning Templates and click Create Template.
    3. Paste the template into the editor and provide a name for the template, such as Image mode kickstart default.
    4. Navigate to the Association tab and select the Satellite operating systems that you want to use with the template during provisioning.
    5. Navigate to Hosts > Provisioning Setup > Operating Systems and select the target operating system.
    6. Navigate to Templates and select the new Image mode kickstart default template.

    Now, when the operating system is selected during provisioning, Satellite renders Image mode kickstart default and serves it to provisioning hosts.

    Secured registries

    Using a container registry that requires authentication to provision an image mode machine is supported. Satellite servers without Unauthenticated Pull configured for its lifecycle environments do require authentication. Configure the pull secrets in the %pre section of the kickstart script:

    %pre
    mkdir -p /etc/ostree
    cat > /etc/ostree/auth.json << 'EOF'
    {
            "auths": {
                    "registry.redhat.io": {
                            "auth": "<your secret here>"
                    }
            }
    }
    EOF
    %end
    

    Kernel options

    The url command is not compatible with ostreecontainer, so you must set inst.stage2 in the kernel options. To do so, populate the host's kickstart_kernel_custom_options parameter with a path to the kickstart repository, which can be found on the repository in Satellite. Edit the path as necessary if using a content view.

    Parameter name: kickstart_kernel_custom_options
    Parameter type: json
    Parameter value (for example): ["inst.stage2=http://satellite.example.com/pulp/content/Demo/Development/RHEL_10/content/dist/rhel10/10.0/x86_64/baseos/kickstart/"]

    Consider setting this on a host group to avoid setting it for each host individually.

    Advanced options for inst.stage2

    There are a few more advanced options for setting the inst.stage2 repository where the medium_uri is calculated automatically:

    1. Query the repository path to avoid manually writing in the kickstart repository path:
    Parameter name: kickstart_kernel_custom_options
    Parameter type: json
    Parameter value: ["inst.stage2=<%= medium_uri >"]
    1. Alternatively, create a new kickstart_kernel_options provisioning template that includes inst.stage2 automatically. Pair with a new PXE template (such as Kickstart default PXELinux) that uses the updated kernel options template.
    2. Or set the kickstart_liveimg parameter on the host to true.

    Network provisioning

    If your environment has the following configured:

    • Satellite configured with managed DHCP, TFTP, and DNS
    • RHEL 9 or 10 AppStream and BaseOS kickstart repositories synced
    • The ability to PXE provision normal RHEL hosts
    • An image mode kickstart template configured as discussed above

    You are now nearly set to provision image mode RHEL machines.

    The image mode provisioning strategy discussed here relies heavily on the kickstart script. Otherwise, the provisioning process is nearly identical for traditional package mode RHEL.

    First, consider the registry source for the host's container image. Satellite's container registry is a good choice for keeping network traffic within your infrastructure and for content lifecycle management. Satellite also has support for certificate authentication via containers-certs.d, which might be useful in future kickstart image mode provisioning strategies. Satellite is not required to be the registry, however. Any container registry can be used within the kickstart file. Keep in mind how Anaconda authenticates with the chosen container registry. If authentication credentials are needed, see the Secured registries section.

    Once the registry source is chosen, it's time to build the host. Proceed with the regular inputs you'd use for package mode RHEL host provisioning, with these changes:

    1. The provisioning templates must resolve to the image mode provisioning ones created earlier. Be sure to choose the operating system associated with the image mode provisioning template.
    2. Create the necessary host parameters for provisioning following the examples:
      • ostreecontainer:
        • Type: string
        • sat.example.com/org/testing/bootc/rhel10-bootc:10.0
      • kickstart_kernel_custom_options:
        • Type: json
        • ["inst.stage2=http://sat.example.com/pulp/content/Demo/Development/RHEL_10/content/dist/rhel10/10.0/x86_64/baseos/kickstart/"]

    Create the host and enable the rendered kickstart and PXE templates in the Details tab for the new host. The kickstart template must include the ostreecontainer command, and the PXE template must include the kickstart repository in the kernel options as inst.stage2.

    Monitor the provisioning process. Once it's complete, you have an image mode machine that's ready for use. To verify, after logging in, run bootc status. Verify that the booted image is set to the same path as the host's ostreecontainer parameter.

    Image-based provisioning

    This image-based provisioning tutorial for virtual machines uses the same Satellite environment as described in the network provisioning section.

    There are multiple ways to create image mode disk images. To take advantage of Satellite's kickstart templates, these tutorial steps result in a reusable base image that can deploy any bootc container as an image mode machine.

    To start, download a RHEL installation image for a version that supports image mode. For this tutorial, the image name is rhel-10.0-x86_64-dvd.iso.

    Install mkksiso from the lorax RPM package available in RHEL's default AppStream repository. Then, as root, use mkksiso to append kickstart kernel options to the RHEL disk image:

    $ mkksiso -c "inst.ks.sendmac inst.ks=http://katello.foreman-nuc1.example.com/unattended/provision" rhel-10.0-x86_64-dvd.iso rhel-10.0-satellite-ks-x86_64.iso
    ...
    xorriso : UPDATE : Writing:    3956736s   95.7%   fifo 100%  buf  50%  882.9xD 
    ISO image produced: 4132704 sectors
    Written to medium : 4132880 sectors at LBA 48
    Writing to 'rhel-10.0-satellite-ks-x86_64.iso' completed successfully.
    ...
    

    Once the new RHEL installation image is created, it needs to be added as an image to a compute resource. For example, if using the libvirt compute resource:

    1. Copy the disk image to the default libvirt volume directory, /var/lib/libvirt/images/
    2. Navigate to Compute Resources > libvirt > Images and select Create Image
    3. Complete the image creation form

    Now Satellite hosts can be created using the new image. As long as the Satellite host's MAC address matches the MAC address of its provisioning network interface, the kickstart template associated with the host's operating system is used by Anaconda at provisioning time.

    If you don't require Anaconda automation for setting up your new image mode RHEL virtual machine, consider using bootc-image-builder directly from a bootc container image. The disk image can be used to create virtual machines in the same manner as above.

    The value of deploying image mode systems with Satellite

    Image mode enables a consistent and automatable approach for managing the operating system lifecycle. RHEL systems running in Image mode are updated by downloading all the updates, which are applied in a single reboot operation. If the updates cause unforeseen problems, they can be reversed without resorting to restoring from backups.

    Red Hat Satellite provides ready-made tooling to facilitate the management lifecycle of image mode systems. As we've seen in this article, Satellite can save you time in provisioning and updating image mode systems.

    The combination of image mode and Satellite removes many steps required to provision and manage large fleets of systems, providing you with speed and flexibility when managing the lifecycle of operating systems.

    Related Posts

    • Control image mode updates with download-only via bootc

    • How to build an image mode pipeline with GitLab

    • Image mode for RHEL 10: Updates in seconds with soft reboot

    • What is an image mode 3-way merge?

    Recent Posts

    • Provisioning image mode for Red Hat Enterprise Linux using Red Hat Satellite

    • Trace Kubernetes resources for llm-d model serving

    • Testing modern hash table designs in OVN and OVS

    • AutoRAG: Optimizing RAG for small models

    • One kernel feature, 93% system throughput gone: A Red Hat Enterprise Linux 10.2 kernel regression and how to mitigate it

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.