Keycloak 21 docker missing microdnf?

I have been able to build my images fine through 20.0.5, but attempting today with v21, I’m getting an error for microdnf not found. Did something change in the base image? My Dockerfile excerpt is below.

FROM quay.io/keycloak/keycloak:latest as builder

ENV KC_METRICS_ENABLED=true
ENV KC_DB=postgres
USER 0
RUN  /usr/bin/microdnf update -y && /usr/bin/microdnf install -y unzip

/bin/sh: line 1: /usr/bin/microdnf: No such file or directory
2 Likes

From what I can tell, KC 21 switched from UBI minimal to UBI micro, making microdnf unavailable. I wish this was included in the release notes on the blog. I’m trying find details of how software gets added to the micro image(“from the underlying host” is non-specifc).

1 Like

Did you figure it out?

Same problem here. I need Kerberos to work in Keycloak. For that I used to add the following to the Keycloak Dockerfile:

RUN microdnf update -y && \\
    microdnf install -y krb5-workstation && \\
    microdnf clean all && \\
    rm -rf /var/cache/yum/*

The solution to add packages to UBI Micro images seems to be to use the tool Buildah: Introduction to Red Hat’s UBI Micro

Now figuring out how to add this to the build process.

You can add static binaries to image but not all software provides those.

I ended up looking into original Dockerfile from https://github.com/keycloak/keycloak/blob/main/quarkus/container/Dockerfile and making my own based how it is made.

Simples would be changing the KEYCLOAK_VERSION and then add required packages to RUN bash /tmp/ubi-null.sh java-17-openjdk-headless glibc-langpack-en line. Remember that you need to copy the ubi-null.sh script also then or use ADD with URL there instead.

If you do not care about size you can just remove the ubi-null stuff. I have not tested these changes, but changes should be something like this:

Replace

FROM registry.access.redhat.com/ubi9 AS ubi-micro-build

with

FROM registry.access.redhat.com/ubi9

Replace

ENV KEYCLOAK_VERSION 999.0.0-SNAPSHOT

with

ENV KEYCLOAK_VERSION 21.0.1

Replace lines

ADD ubi-null.sh /tmp/

RUN bash /tmp/ubi-null.sh java-17-openjdk-headless glibc-langpack-en

FROM registry.access.redhat.com/ubi9-micro

ENV LANG en_US.UTF-8

COPY --from=ubi-micro-build /tmp/null/rootfs/ /

COPY --from=ubi-micro-build --chown=1000:0 /opt/keycloak /opt/keycloak

with

ENV LANG en_US.UTF-8
RUN dnf install -y java-17-openjdk-headless glibc-langpack-en

The official documentation https://www.keycloak.org/server/containers actually uses curl that is not found from image and does not explain how it got there.

So I hope in future they provide us with extensible image or real instructions how they ment to extend current one.

This issue and corresponding PR for docs is perhaps interesting for you:

2 Likes

Thanks for the pointer @dasniko!

The updated documentation describes exactly what I am looking for:
https://github.com/ASzc/keycloak/blob/f6d532d25c3dc65d6f180382e01bef3b8ec35bfe/docs/guides/src/main/server/containers.adoc#installing-additional-rpm-packages

1 Like

Hi @mtn88 @dasniko @foo ,

I tried using the approach mentioned in the document keycloak/containers.adoc at f6d532d25c3dc65d6f180382e01bef3b8ec35bfe · ASzc/keycloak · GitHub but I am getting the below error on dnf install step where I am trying to install the new packages. Below is the code I added in Dockerfile only for testing. When I run this the image gets created successfully.

FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
RUN mkdir -p /mnt/rootfs
RUN dnf install --installroot /mnt/rootfs tar --releasever 9 --sslverify=false --setopt install_weak_deps=false --nodocs -y; dnf --installroot /mnt/rootfs clean all

But when I SSH into my container and check the content of the file /mnt/rootfs/var/log/dnf.log, I can see the error below. Any help would be really appreciated.

2023-04-13T19:27:58+0000 INFO --- logging initialized ---
2023-04-13T19:27:58+0000 DDEBUG timer: config: 1 ms
2023-04-13T19:27:58+0000 DEBUG Loaded plugins: builddep, changelog, config-manager, copr, debug, debuginfo-install, download, generate_completion_cache, groups-manager, needs-restarting, playground, product-id, repoclosure, repodiff, repograph, repomanage, reposync, subscription-manager, uploadprofile
2023-04-13T19:27:58+0000 INFO Updating Subscription Management repositories.
2023-04-13T19:27:58+0000 INFO Unable to read consumer identity
2023-04-13T19:27:58+0000 INFO Subscription Manager is operating in container mode.
2023-04-13T19:27:58+0000 INFO
This system is not registered with an entitlement server. You can use subscription-manager to register.

2023-04-13T19:27:58+0000 DEBUG DNF version: 4.12.0
2023-04-13T19:27:58+0000 DDEBUG Command: dnf install --installroot /mnt/rootfs tar --releasever 9 --setopt install_weak_deps=false --nodocs -y
2023-04-13T19:27:58+0000 DDEBUG Installroot: /mnt/rootfs
2023-04-13T19:27:58+0000 DDEBUG Releasever: 9
2023-04-13T19:27:58+0000 DEBUG cachedir: /mnt/rootfs/var/cache/dnf
2023-04-13T19:27:58+0000 DDEBUG Base command: install
2023-04-13T19:27:58+0000 DDEBUG Extra commands: ['install', '--installroot', '/mnt/rootfs', 'tar', '--releasever', '9', '--setopt', 'install_weak_deps=false', '--nodocs', '-y']
2023-04-13T19:27:58+0000 DEBUG User-Agent: constructed: 'libdnf (Red Hat Enterprise Linux 9.1; generic; Linux.x86_64)'
2023-04-13T19:27:58+0000 DEBUG repo: downloading from remote: ubi-9-baseos-rpms
2023-04-13T19:27:59+0000 DEBUG error: Curl error (60): SSL peer certificate or SSH remote key was not OK for https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml [SSL certificate problem: unable to get local issuer certificate] (https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml).
2023-04-13T19:27:59+0000 DEBUG error: Curl error (60): SSL peer certificate or SSH remote key was not OK for https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml [SSL certificate problem: unable to get local issuer certificate] (https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml).
2023-04-13T19:27:59+0000 DEBUG error: Curl error (60): SSL peer certificate or SSH remote key was not OK for https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml [SSL certificate problem: unable to get local issuer certificate] (https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml).
2023-04-13T19:27:59+0000 DEBUG error: Curl error (60): SSL peer certificate or SSH remote key was not OK for https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml [SSL certificate problem: unable to get local issuer certificate] (https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml).
2023-04-13T19:27:59+0000 WARNING Errors during downloading metadata for repository 'ubi-9-baseos-rpms':
  - Curl error (60): SSL peer certificate or SSH remote key was not OK for https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/repodata/repomd.xml [SSL certificate problem: unable to get local issuer certificate]
2023-04-13T19:27:59+0000 DDEBUG Cleaning up.

I don’t know if this will help anyone, as I don’t think it’s desirable solution, but the podman toolset allows you use an external package manager to install into your image. This allows you to use the keycloak image, as-is.

podman pull quay.io/keycloak/keycloak:latest
builderKC=$(buildah from quay.io/keycloak/keycloak:latest)
bkcdir=$(buildah mount $builderKC)
dnf install --installroot $bkcdir  --setopt install_weak_deps=false  --nodocs -y <your package list goes here>
dnf clean all --installroot $bkcdir
buildah umount $builderKC
buildah commit $builderKC keycloak-builder

If you are using dockerd, the image format isn’t compatible or podman/buildah uses a different registry. This is what I used to export the result:

podman save --format=docker-archive -o kcb.tar localhost/keycloak-builder
chmod a+r kcb.tar

And then using docker build tools:

sh 'docker load -i kcb.tar'

I found this inelegant and slow, and would recommend looking at the git issue to try to find easier ways to satisfy each individual use case. In my case, this was the stopgap I used to get contents from the builder image into my final image.