RHEL Subscription Entitlement for bootc in OCI image

Subscription entitlement bootc

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.

More Posts about bootc