A Go-based image builder that wraps buildah to create layered OS images with support for multiple package managers. It is the next-generation replacement for the Python-based image-builder tool used by OpenCHAMI.
- Multiple package managers — DNF, Zypper, APT (parent builds only), mmdebstrap (scratch builds only)
- Scratch & parent builds — build from
scratchor layer on top of an existing image - Declarative YAML config with a
validatesubcommand - Multiple publishers — local container storage, SquashFS, container registry, S3
- OpenSCAP scanning — XCCDF benchmarks + OVAL vulnerability evaluation
- Structured logging — JSON or text, configurable levels
The pre-built unified image includes every supported package manager.
podman pull ghcr.io/openchami/image-thrillhouse:latestSee docs/container-usage.md for the full podman run invocation and flag explanations.
Grab the .rpm for your architecture from the latest release and install it:
sudo dnf install ./image-thrillhouse-<version>.<arch>.rpmbuildah is a hard dependency; squashfs-tools and podman are recommended/suggested.
Grab the .deb for your architecture from the latest release and install it:
sudo apt install ./image-thrillhouse_<version>_<arch>.debbuildah is a hard dependency; squashfs-tools is recommended and podman is suggested.
For development or unsupported platforms, see docs/development.md.
Save the following as rocky-base.yaml:
meta:
name: rocky-base
tags:
- "9.5"
from: scratch
layer:
manager:
name: dnf
options:
releasever: "9" # required for DNF scratch builds
config: |
[main]
gpgcheck=1
reposdir=/etc/image-thrillhouse/yum.repos.d
repos:
- path: /etc/image-thrillhouse/yum.repos.d/rocky-baseos.repo
content: |
[rocky-baseos]
name=rocky-baseos
baseurl=https://dl.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os
enabled=1
gpgcheck=1
gpgkey=https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
actions:
install:
packages:
- kernel
- systemd
publish:
- type: localValidate, then build:
image-thrillhouse validate --config rocky-base.yaml
image-thrillhouse build --config rocky-base.yaml --log-level infovalidate checks YAML syntax, required fields, backend option names/values, and publisher config — useful in CI before a full build.
The publish section is a list, so you can fan out to multiple targets in one build. To produce a bootable SquashFS file alongside the local image:
publish:
- type: local
- type: squashfs
path: /output/images # writes <meta.name>-<meta.tags[0]>.squashfsFor registry and S3 targets, see docs/configuration.md#publish.
image-thrillhouse build --config <path> # build an image
image-thrillhouse validate --config <path> # validate config without building
image-thrillhouse version # print version infoGlobal flags:
--log-level—debug|info|warn|error(defaultinfo)--log-format—json|text(defaultjson)
- Start with
validate. Runimage-thrillhouse validatein CI before any build — it catches typos in backend options and missing required fields before you pay for a long package download. - Use the unified container. It already has DNF, Zypper, APT, and mmdebstrap. Switching distros is a config change, not an image change. See docs/container-usage.md.
- Always set
releaseverfor DNF scratch builds. This is the most common scratch-build failure mode. See docs/configuration.md. - Use
remove_packagesto slim images. Drop debug packages, docs, and unused firmware in the same step that installs the base — see docs/configuration.md#package-removal. - Pin image tags in production. Use
ghcr.io/openchami/image-thrillhouse:v0.1.0rather than:latestfor reproducible builds.
- Configuration reference — every field in the YAML, with examples
- Container usage — running the pre-built image, flag explanations, multi-version DNF
- Package manager support — backend feature matrix
- Example configs — annotated index of
tests/configs - Development — building, testing, architecture, adding backends/publishers
- Troubleshooting — common errors
- Migration from the Python image-builder
- Unit testing guide
- Buildah — container building tool
- Podman — container runtime
- OpenCHAMI — HPC cluster management (original use case)
Issues and PRs are welcome. Areas of interest include additional package managers (pacman, apk, …), additional publishers (Azure, GCP, …), broader test coverage, and build-time optimization.
See LICENSE.
The majority of the documentation and some of the code was written by Claude Sonnet 4.5 (training cutoff September 29, 2025). All generated content has been verified and tested.