Building a bootc image for Red Hat Enterprise Linux (RHEL) “Image Mode” requires Red Hat Subscription Entitlement details. The Red Hat documentation says to build the image on a “Subscribed RHEL 9.x system”. But what if the build server is using a bootc based host?!? Or what if the build server isn’t the same version of RHEL as the bootc image being built? How do I add my Red Hat Subscription information directly into a bootc image build? This is similar to the previous post “Build RHEL UBI containers with previous package versions“, but taken even further.
TL;DR: Put all the Subscription information into it’s own container image. Then it’s easy to “consume” in the build steps.
Build Subscription Entitlement image for bootc
Create a Containerfile to build a RHEL UBI image to save only the Red Hat Subscription Entitlement after registering the a RHEL Satellite using subscription-manager
, using a scratch
image.
A scratch
image is used to create a small image with only what is needed, in this case it will only be a few files.
Site note: If the below Containerfile looks strange, it’s because of heredocs. See my other post about using heredoc in a Dockerfile / Containerfile.
The rhel_entitlement.Containerfile
:
FROM registry.access.redhat.com/ubi9/ubi:latest as build
RUN \
<<EOF bash
subscription-manager register --org=TEAM1 --activationkey=TEAM1_RedHat9
mkdir -p rhel_entitlement
cd rhel_entitlement || exit 1
mkdir -p rhsm-mount/etc-pki-entitlement
mkdir -p "rhsm-mount/rhsm
touch rhsm-mount/redhat.repo
cp -rp /etc/pki/entitlement/* rhsm-mount/etc-pki-entitlement
cp -rp /etc/rhsm/* rhsm-mount/rhsm
awk '/-appstream-/' RS= ORS="\n\n" /etc/yum.repos.d/redhat.repo >> rhsm-mount/redhat.repo
awk '/-baseos-/' RS= ORS="\n\n" /etc/yum.repos.d/redhat.repo >> rhsm-mount/redhat.repo
subscription-manager unregister
EOF
FROM scratch
COPY --from=build /rhel_entitlement/rhsm-mount/ /rhel_entitlement/rhsm-mount/
Now build the entitlement image and push it to an internal registry (Do not save this image to Docker Hub!):
docker build . \
--pull \
--no-cache \
--progress=plain \
-f rhel_entitlement.Containerfile \
--build-arg HOSTNAME=entitlement \
--build-arg BUILDKIT_SANDBOX_HOSTNAME=entitlement \
--tag myregistry/rhel-entitlement/rhel9:latest
docker push myregistry/rhel-entitlement/rhel9:latest
Now the entitlement image is accessible from an internal registry.
Use Subscription Entitlement image when building bootc image
When building a bootc image, reference the entitlement image in the relevant RUN
section as a bind mount, and the Subscription entitlement files will automatically be used. See Dockerfile reference for bind mount from an image.
The bootc-rhel9.Containerfile
:
FROM registry.redhat.io/rhel9/rhel-bootc:latest
RUN --mount=type=bind,from=myregistry/rhel-entitlement/rhel9:latest,source=/rhel_entitlement/rhsm-mount/,target=/run/secrets/ \
<<EOF bash
# Do stuff that needs entitlement
dnf upgrade -y
dnf install -y vim tmux
# Cleanup
dnf clean all
rm -rf /var/cache/yum
EOF
Build and push the bootc image like normal:
docker build . \
--pull \
--no-cache \
--progress=plain \
-f bootc-rhel9.Containerfile \
--tag myregistry/rhel-bootc/rhel9:latest
docker push myregistry/rhel-bootc/rhel9:latest
Conclusion
This is an easy way to create a scratch image with only the RHEL entitlement files, for use when building a bootc image. This is also useful for regular container builds of RHEL UBI images when needing to install a previous package version.