bootc / Image-Mode RHEL
Deliver the operating system as an immutable OCI container image with atomic updates and automatic rollbacks.
What is bootc?
bootc is a tool for managing bootable container images. It enables image-mode RHEL, where the entire operating system — kernel, packages, configuration — is delivered as a standard OCI container image. Instead of managing individual RPM packages on each machine, you build a container image with your desired OS state and deploy it.
bootc vs. Traditional Package Management
| Aspect | Traditional (dnf/yum) | bootc (Image-Mode) |
|---|---|---|
| Update unit | Individual RPM packages | Entire OS image (atomic) |
| Rollback | Manual, unreliable | Automatic, guaranteed (previous image retained) |
| Drift | Possible (manual changes accumulate) | Eliminated (OS state defined by image) |
| Build process | Kickstart / Ansible / manual | Containerfile (standard container build) |
| Registry | RPM repos (dnf/yum) | OCI container registry (Quay, GHCR, etc.) |
| Testing | Test on live system | Test image in CI before deploying |
| Reproducibility | Depends on repo state at install time | Fully reproducible (pinned image digest) |
How bootc Updates Work in This Golden Path
When you select bootc Image as the boot source, the template configures automatic OS updates inside the VM guest:
-
Systemd Timer — A
bootc-update.timerunit is injected via cloud-init and runs daily (OnCalendar=daily,Persistent=true). -
Pull & Stage — The timer triggers
bootc update --apply, which pulls the latest version of the bootc image from the registry and stages it for the next boot. - Reboot & Activate — On the next reboot (manual or scheduled), the new OS image is activated. The previous image is retained as a rollback target.
- Automatic Rollback — If the new image fails to boot successfully, bootc automatically rolls back to the previous known-good image.
Building Custom bootc Images
You build bootc images using standard container tooling (Podman, Buildah, Docker). Start from a base bootc image and layer your customizations:
Basic Containerfile
FROM quay.io/centos-bootc/centos-bootc:stream9
# Install packages
RUN dnf install -y \
httpd \
vim-enhanced \
git \
&& systemctl enable httpd \
&& dnf clean all
# Add custom configuration
COPY my-httpd.conf /etc/httpd/conf.d/custom.conf
# Add application content
COPY html/ /var/www/html/
Build and Push
# Build the image
podman build -t quay.io/myorg/my-rhel-bootc:v1.0 .
# Push to registry
podman push quay.io/myorg/my-rhel-bootc:v1.0
Multi-Stage Build with Testing
FROM quay.io/centos-bootc/centos-bootc:stream9 AS base
RUN dnf install -y httpd php php-mysqlnd && \
systemctl enable httpd && \
dnf clean all
COPY app/ /var/www/html/
COPY httpd-8080.conf /etc/httpd/conf.d/listen-8080.conf
# Verify the image builds correctly
RUN httpd -t
GitOps-Driven OS Lifecycle
The golden path integrates bootc with ArgoCD for a complete GitOps-driven OS lifecycle:
┌─────────────────┐ ┌──────────────┐ ┌───────────────┐
│ Build bootc │ │ Push image │ │ Update YAML │
│ image in CI │────►│ to Quay.io │────►│ in Git repo │
│ (Containerfile) │ │ │ │ (image ref) │
└─────────────────┘ └──────────────┘ └──────┬────────┘
│
▼
┌───────────────┐
│ ArgoCD syncs │
│ DataVolume │
│ (new image) │
└──────┬────────┘
│
▼
┌───────────────┐
│ VM boots with │
│ new OS image │
└───────────────┘
Updating the Image via Git
To update the OS image for a running VM:
- Build and push the new bootc image with a new tag
- Edit
manifests/virtualmachine.yamlin the Gitea repository - Update the
bootcImageUrlto the new image tag - Commit and push to
main - ArgoCD detects the change and reconciles the DataVolume
# In manifests/virtualmachine.yaml, update the source:
source:
registry:
url: "docker://quay.io/myorg/my-rhel-bootc:v1.1" # Updated tag
pullMethod: node
In-Guest bootc Commands
Once connected to the VM via SSH, you can manage bootc directly:
# Check current boot status
bootc status
# Manually check for updates
bootc update --check
# Apply an update immediately
bootc update --apply
# Switch to a different image entirely
bootc switch quay.io/myorg/my-rhel-bootc:v2.0
# Rollback to the previous image
bootc rollback
Base Images
| Image | Description | Use Case |
|---|---|---|
quay.io/centos-bootc/centos-bootc:stream9 |
CentOS Stream 9 bootc base image | Development, testing, community use |
registry.redhat.io/rhel9/rhel-bootc:latest |
RHEL 9 bootc base image (subscription required) | Production workloads with Red Hat support |