Build your customized Keycloak image

Lejdi Prifti
3 min readNov 10, 2023

Keycloak occasionally does not provide the functionalities that our clients or us desire. In this scenario, what should we do?

Inform the client that we are unable to complete the task? Not at all! We modify the open source code.

I’ll walk you through creating a unique Keycloak image that suits your needs in this post.

Keycloak with Docker

If you are working with the latest Keycloak version, then you can go to the Github repository, create a fork and clone the repository.

https://github.com/keycloak/keycloak

If you are not working with the latest version, then you must find the source code of the version you are using in the Releases page.

https://github.com/keycloak/keycloak/releases

Pay attention! Always work with the source code of the version you are already using.

For example, if the current Keycloak running on your Kubernetes cluster is 21.0.5, you will need to use the source code of that version, and not the latest 22.0.5 that introduces breaking changes.

My client requested to introduce a timer when sending verification emails. Luckily, I was working with the latest version of the Keycloak, so I directly forked the repository, modified the code and created a PR also for the community. The PR is still pending approval.

Let’s get to the main topic now!

To get the Dockerfile for building a Keycloak image, you must go to this Github repository and locate the keycloak folder.

https://github.com/bitnami/containers

The Dockerfile will look as follows and I stored it in the root directory of the Keycloak source code to use it later.

FROM docker.io/bitnami/minideb:bullseye

ARG JAVA_EXTRA_SECURITY_DIR="/bitnami/java/extra-security"
ARG TARGETARCH

LABEL com.vmware.cp.artifact.flavor="sha256:1e1b4657a77f0d47e9220f0c37b9bf7802581b93214fff7d1bd2364c8bf22e8e" \
org.opencontainers.image.base.name="docker.io/bitnami/minideb:bullseye" \
org.opencontainers.image.created="2023-10-24T13:50:10Z" \
org.opencontainers.image.description="Application packaged by VMware, Inc" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.ref.name="22.0.5-debian-11-r0" \
org.opencontainers.image.title="keycloak" \
org.opencontainers.image.vendor="VMware, Inc." \
org.opencontainers.image.version="22.0.5"

ENV HOME="/" \
OS_ARCH="${TARGETARCH:-amd64}" \
OS_FLAVOUR="debian-11" \
OS_NAME="linux"

COPY prebuildfs /
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Install required system packages and dependencies
RUN install_packages ca-certificates curl krb5-user libaio1 procps zlib1g
RUN mkdir -p /tmp/bitnami/pkg/cache/ && cd /tmp/bitnami/pkg/cache/ && \
COMPONENTS=( \
"wait-for-port-1.0.7-2-linux-${OS_ARCH}-debian-11" \
"java-17.0.9-11-1-linux-${OS_ARCH}-debian-11" \
) && \
for COMPONENT in "${COMPONENTS[@]}"; do \
if [ ! -f "${COMPONENT}.tar.gz" ]; then \
curl -SsLf "https://downloads.bitnami.com/files/stacksmith/${COMPONENT}.tar.gz" -O ; \
curl -SsLf "https://downloads.bitnami.com/files/stacksmith/${COMPONENT}.tar.gz.sha256" -O ; \
fi && \
sha256sum -c "${COMPONENT}.tar.gz.sha256" && \
tar -zxf "${COMPONENT}.tar.gz" -C /opt/bitnami --strip-components=2 --no-same-owner --wildcards '*/files' && \
rm -rf "${COMPONENT}".tar.gz{,.sha256} ; \
done

################# BEGIN MODIFY WITH YOUR OWN CODE ####################

COPY quarkus/dist/targetkeycloak-22.0.5.tar.gz /tmp/bitnami/pkg/cache/keycloak-22.0.5-linux-amd64-debian-11.tar.gz

ENV COMPONENT="keycloak-22.0.5-linux-amd64-debian-11"
RUN cd /tmp/bitnami/pkg/cache/ && \
tar -zxf "${COMPONENT}.tar.gz" -C /opt/bitnami && \
rm -rf "${COMPONENT}".tar.gz

################# END MODIFY WITH YOUR OWN CODE ####################

RUN apt-get update && apt-get upgrade -y && \
apt-get clean && rm -rf /var/lib/apt/lists /var/cache/apt/archives
RUN chmod g+rwX /opt/bitnami

COPY rootfs /
RUN /opt/bitnami/scripts/java/postunpack.sh
RUN /opt/bitnami/scripts/keycloak/postunpack.sh
ENV APP_VERSION="22.0.5" \
BITNAMI_APP_NAME="keycloak" \
JAVA_HOME="/opt/bitnami/java" \
PATH="/opt/bitnami/common/bin:/opt/bitnami/java/bin:/opt/bitnami/keycloak/bin:$PATH"

USER 1001
ENTRYPOINT [ "/opt/bitnami/scripts/keycloak/entrypoint.sh" ]
CMD [ "/opt/bitnami/scripts/keycloak/run.sh" ]

In the code above, I have marked the parts that you need to modify with #. To build Keycloak, you can follow the file building.md that is inside every source code of Keycloak.

I have built the Keycloak distribution running the command below which will generate the .tar.gz file inside the quarkus/dist/target folder.

mvn clean install -Pdistribution -DskipTests

The only task remaining is to construct the Docker image.

docker build -t keycloak:customer .

--

--

Lejdi Prifti

Software Developer | ML Enthusiast | AWS Practitioner | Kubernetes Administrator