Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation

    Image Builder is a system image building tool provided by Red Hat-based distributions. It creates custom OS images for various platforms, including ISO, qcow2 (KVM/OpenStack), AMI (AWS), VMDK (VMware), and more. This guide covers installing Image Builder, creating blueprints with both the cockpit-composer web interface and the composer-cli command-line tool, building images, and customizing configurations.

    Image Builder consists of two main components:

    • osbuild-composer — The backend build service responsible for the actual image creation
    • composer-cli — Command-line tool for managing blueprints and build tasks
    • cockpit-composer — A graphical plugin for the Cockpit web interface
    FormatUse Case
    qcow2KVM / OpenStack / general virtualization
    vmdkVMware
    vhdMicrosoft Azure / Hyper-V
    amiAmazon Web Services
    isoBootable installation ISO
    tarGeneric tar archive
    gceGoogle Cloud Platform
    rawRaw disk image
    Install osbuild-composer and CLI tools
    sudo dnf install osbuild-composer composer-cli -y
    Install Cockpit web interface (optional)
    sudo dnf install cockpit cockpit-composer -y
    Start and enable the osbuild-composer service
    sudo systemctl enable --now osbuild-composer.socket
    Start Cockpit (if installed)
    sudo systemctl enable --now cockpit.socket
    sudo firewall-cmd --permanent --add-service=cockpit
    sudo firewall-cmd --reload

    After installation, access the Cockpit graphical interface via browser at https://<server-IP>:9090.

    Add current user to the weldr group (to use composer-cli)
    sudo usermod -aG weldr $(whoami)
    newgrp weldr
    Verify composer-cli is working
    composer-cli status show

    A blueprint is a TOML-format configuration file that defines the packages and settings to include in an image.

    Create a base blueprint file
    cat > /tmp/my-server.toml << 'EOF'
    name = "my-server"
    description = "Custom server image for production deployment"
    version = "1.0.0"
    distro = ""
    # Packages to include
    [[packages]]
    name = "vim-enhanced"
    version = "*"
    [[packages]]
    name = "wget"
    version = "*"
    [[packages]]
    name = "curl"
    version = "*"
    [[packages]]
    name = "chrony"
    version = "*"
    [[packages]]
    name = "bash-completion"
    version = "*"
    [[packages]]
    name = "net-tools"
    version = "*"
    [[packages]]
    name = "tmux"
    version = "*"
    [[packages]]
    name = "htop"
    version = "*"
    # Package groups
    [[groups]]
    name = "core"
    # Custom kernel parameters (optional)
    [customizations.kernel]
    append = "net.ifnames=0"
    # Set timezone
    [customizations.timezone]
    timezone = "America/New_York"
    ntpservers = ["time.google.com", "time.cloudflare.com"]
    # Set locale
    [customizations.locale]
    languages = ["en_US.UTF-8"]
    keyboard = "us"
    # Create user
    [[customizations.user]]
    name = "admin"
    description = "Admin user"
    password = "$6$rounds=4096$randomsalt$hashedpassword"
    groups = ["wheel"]
    # Firewall settings
    [customizations.firewall]
    ports = ["22:tcp", "80:tcp", "443:tcp"]
    # Service configuration
    [customizations.services]
    enabled = ["chronyd", "sshd", "firewalld"]
    disabled = ["postfix"]
    EOF
    Push the blueprint to Image Builder
    composer-cli blueprints push /tmp/my-server.toml
    List all blueprints
    composer-cli blueprints list
    View blueprint details
    composer-cli blueprints show my-server
    Resolve blueprint dependencies
    composer-cli blueprints depsolve my-server
    Export blueprint to a TOML file
    composer-cli blueprints save my-server
    Delete a blueprint
    composer-cli blueprints delete my-server

    The workflow for modifying a blueprint is: export -> edit -> re-push.

    Export the blueprint
    composer-cli blueprints save my-server
    Edit the blueprint file
    vi my-server.toml
    Push the updated blueprint
    composer-cli blueprints push my-server.toml
    Build a qcow2 image (for KVM/OpenStack)
    composer-cli compose start my-server qcow2
    Build an ISO installation image
    composer-cli compose start my-server iso
    Build an AMI image (for AWS)
    composer-cli compose start my-server ami
    Build a VMDK image (for VMware)
    composer-cli compose start my-server vmdk
    Build a VHD image (for Azure)
    composer-cli compose start my-server vhd
    View all build tasks
    composer-cli compose list
    View running builds
    composer-cli compose status

    Build states progress through: WAITING -> RUNNING -> FINISHED or FAILED.

    Download the completed image
    composer-cli compose image <UUID>

    Replace <UUID> with the actual UUID of the build task (obtained from composer-cli compose list).

    Download build logs (for troubleshooting)
    composer-cli compose logs <UUID>
    View build metadata
    composer-cli compose metadata <UUID>
    Delete a completed build
    composer-cli compose delete <UUID>

    You can embed custom configuration files directly in the blueprint:

    Embed custom files in the blueprint
    cat >> /tmp/my-server.toml << 'EOF'
    # Custom files
    [[customizations.files]]
    path = "/etc/motd"
    data = "Welcome to My Custom Server\n"
    [[customizations.files]]
    path = "/etc/sysctl.d/99-custom.conf"
    data = "vm.swappiness=10\nnet.core.somaxconn=65535\n"
    EOF
    Hostname in blueprint
    [customizations.hostname]
    hostname = "prod-server-01"
    Create a web server blueprint
    cat > /tmp/web-server.toml << 'EOF'
    name = "web-server"
    description = "Nginx web server image"
    version = "1.0.0"
    [[packages]]
    name = "nginx"
    version = "*"
    [[packages]]
    name = "certbot"
    version = "*"
    [[packages]]
    name = "python3-certbot-nginx"
    version = "*"
    [[packages]]
    name = "vim-enhanced"
    version = "*"
    [[packages]]
    name = "chrony"
    version = "*"
    [customizations.services]
    enabled = ["nginx", "chronyd", "sshd", "firewalld"]
    [customizations.firewall]
    ports = ["22:tcp", "80:tcp", "443:tcp"]
    [customizations.timezone]
    timezone = "UTC"
    [[customizations.user]]
    name = "deploy"
    groups = ["wheel"]
    EOF
    Push and build the web server image
    composer-cli blueprints push /tmp/web-server.toml
    composer-cli compose start web-server qcow2

    If cockpit-composer is installed, you can use the web interface for visual management:

    1. Open a browser and navigate to https://<server-IP>:9090
    2. Log in with your system account
    3. Select Image Builder from the left menu
    4. Click Create Blueprint to create a new blueprint
    5. Use the search box to add required packages
    6. Configure customization options
    7. Click Create Image, select the output format, and start the build
    8. Download the completed image from the Images tab
    Create a VM using the built qcow2 image
    sudo virt-install \
    --name my-server \
    --ram 2048 \
    --vcpus 2 \
    --import \
    --disk path=/path/to/<UUID>-disk.qcow2 \
    --os-variant almalinux9 \
    --nographics

    The built AMI image can be uploaded using the AWS CLI:

    Upload AMI to S3 and register
    aws s3 cp <UUID>-image.raw s3://my-bucket/my-server.raw
    aws ec2 import-image --disk-containers "file://containers.json"

    For more complex image building pipelines, consider using HashiCorp Packer. Packer supports more builders and integrates with configuration management tools.

    Install Packer (EL 9 / EL 10)
    sudo dnf install -y dnf-plugins-core
    sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
    sudo dnf install packer -y
    Verify Packer installation
    packer version

    Packer uses HCL or JSON templates to define the image build process, supports QEMU, VMware, AWS, Azure, GCP, and many other builders, and integrates with Ansible, Shell scripts, and other configuration management tools.

    Image Builder vs Packer comparison:

    FeatureImage BuilderPacker
    IntegrationNatively integrated with EL systemsThird-party tool
    Learning curveLowMedium
    FlexibilityMediumHigh
    CI/CD integrationBasicExcellent
    Multi-platform supportGoodExcellent
    Config managementLimitedAnsible/Chef/Puppet/Shell
    1. Version control blueprints — Store TOML blueprint files in a Git repository
    2. Use meaningful version numbers — Update the version number each time you modify a blueprint
    3. Validate in test environments first — Deploy and verify built images in test environments before production
    4. Rebuild regularly — Include the latest security patches
    5. Minimize the installation — Only include required packages to reduce the attack surface
    6. Leverage custom files — Embed standard configurations in images to reduce post-deployment work
    7. Record build information — Save build UUIDs and corresponding blueprint versions