Extending the System via Dockerfiles
Objective
By the end of this quickstart, you will be able to:
- kairosify a Hadron base image with
kairos-init - add an additional tool during build time (we’ll install
btm) - publish your custom image to an OCI registry
Now that you’ve launched your first Kubernetes cluster on Hadron, you might want to extend the system. Kairos supports multiple approaches for this—Dockerfiles, systemd system extensions, and bundles. There isn’t a single “best” option: each has trade-offs, and the right choice depends on your needs. In this quickstart, we’ll extend the system using a Dockerfile.
Prerequisites
Alternatives
This tutorial uses the recommended container and virtualization tools to keep the instructions simple. Other alternatives should work as well, but they’re not documented here. If you successfully follow the tutorial using different tools, please consider opening a PR so others can benefit from your steps.To extend and run Hadron, you’ll need a container engine and virtualization software that can run (or emulate) the amd64 architecture. In this guide, we’ll use:
Prefer to watch a video?
Building
Hadron by itself is not immutable. To get the full Kairos experience—immutability, atomic upgrades, and more—we first need to initialize (often called “kairosify”) the system using kairos-init.
Create a Dockerfile with the following content:
FROM quay.io/kairos/kairos-init:v0.6.8 AS kairos-init
FROM ghcr.io/kairos-io/hadron:v0.0.1-beta2 AS base
ARG VERSION
RUN --mount=type=bind,from=kairos-init,src=/kairos-init,dst=/kairos-init \
eval /kairos-init -l debug -s install --model generic --provider k3s --version \"${VERSION}\" && \
eval /kairos-init -l debug -s init --model generic --provider k3s --version \"${VERSION}\"
Build it with the following command. Here, 0.1.0 is the version we’re assigning to my-hadron. We tag the image and also pass the version as a build argument so kairos-init writes it into /etc/kairos-release. We’ll use that in later steps.
arm64
Hadron is currently in beta, and only amd64 images are available at the moment. If you’re running on arm64, you’ll need to build for amd64.docker build -t my-hadron:0.1.0 --build-arg=VERSION=0.1.0 .
If the command finishes successfully, you should see my-hadron among your local images:
docker images | grep my-hadron
my-hadron 0.1.0 5effd0969bfe 4 minutes ago 397MB
Adding a binary
Hadron doesn’t ship with a package manager. That means the two straightforward options to extend the system are:
- build packages yourself, or
- add a prebuilt binary.
To keep this quickstart short, we’ll use the second approach.
As an example, we’ll download and install bottom (btm) to inspect system resource usage.
Toolchain
In this example we use the Hadronhadron-toolchain image as a build stage. It contains a full build environment (gcc, make, headers, etc.) that is not included in the final production images—useful for build-time tasks, but typically avoided at runtime for security and size reasons.FROM quay.io/kairos/kairos-init:v0.6.4 AS kairos-init
FROM ghcr.io/kairos-io/hadron-toolchain:v0.0.1-beta1 AS bottom
RUN curl -L -o bottom.tar.gz https://github.com/ClementTsang/bottom/releases/download/0.11.4/bottom_x86_64-unknown-linux-musl.tar.gz
RUN tar xvzf bottom.tar.gz
FROM ghcr.io/kairos-io/hadron:v0.0.1-beta1 AS base
ARG VERSION
RUN --mount=type=bind,from=kairos-init,src=/kairos-init,dst=/kairos-init \
eval /kairos-init -l debug -s install --provider k3s --version \"${VERSION}\" && \
eval /kairos-init -l debug -s init --provider k3s --version \"${VERSION}\"
COPY --from=bottom /btm /usr/bin/btm
Now build the image again, but assign a new version. Since we’re using SemVer, bumping the minor version to 0.2.0 is a good next step. This makes it easy to distinguish images and perform upgrades.
docker build -t my-hadron:0.2.0 --build-arg=VERSION=0.2.0 .
Next, push the image to a registry you can access. If you don’t have one available, you can use ttl.sh.
Keep in mind ttl.sh is an anonymous registry, so an image with the same name might already exist—use a unique image name.
docker tag my-hadron:0.2.0 ttl.sh/my-hadron:0.2.0
docker push ttl.sh/my-hadron:0.2.0
Conclusion
Congratulations—you’ve successfully extended a Hadron image.
What’s Next?
Other ways to extend the system
Extend with systemd extensionsContinue the quickstart
If you’re new to Kairos, follow these in order to learn the full workflow: build a custom image, upgrade atomically, then harden the system.
Upgrade & rollback (atomic upgrades) Trusted Boot (TPM + Secure Boot) quickstartDeep dive docs
If you’re already comfortable with Kairos and want details, jump straight to the reference docs.
Cloud-config referenceFrequently Asked Questions (FAQs)
What is the hadron-toolchain container for?
Hadron builds many packages that are available in the toolchain image but are not included in the final production images. They’re useful for building code from source and other build-time tasks, but you typically avoid shipping them at runtime for security and size reasons.
Can I have a specific version of Kubernetes?
Yes, with the --provider flag you can define if you want k3s or k0s installed, and with the --provider-k3s-version and --provider-k0s-version respectively, you can define the exact version to install.
What if I don’t need Kubernetes?
No problem—remove the --provider flag from kairos-init and you’ll get a core image without Kubernetes installed.