[keycloak-dev] [Keycloak Operator] Builder image

Sebastian Laskawiec slaskawi at redhat.com
Mon Nov 25 05:04:39 EST 2019


Greetings!

When we were working on Keycloak Operator, we introduced a hacky solution
for building our image [1]. It uses a shell script to build the binaries
[2], which turned out to be problematic in Quay due reusing build cache
[3]. This resulted in our builds containing old binaries, which was
critical to fix. We found a workaround but I wanted to revisit this issue
with something better...

In Pull Request #96 [4] I came up with a solution that uses Docker
Multi-Stage builds. In short - the build is divided into 2 stages. The
first one creates a container that builds our binaries (so called a builder
container) and then we copy them (the binaries) to the final container. The
whole point is that the final container doesn't need to contain Golang,
Make or any other things necessary to build binaries.

This approach has the following advantages:
- It makes the image smaller - from ~250 MB to ~54 MB (see [5][6]).
- It's just a pure UBI8 image with zero other dependencies, which means
smaller CVE surface.
- This approach fixes operator-hub build command.
- It allows to play with build cache using --cache-from (so that you can
reuse previous build results and modify only the final image).

However, there are some drawbacks as well:
- Say bye bye to Docker 1.13 (which is installed by default on Fedora OS).
Multi-stage builds require newer Docker version or Podman [*].
- Dockerfile had to be moved to project's root. As the build process pulls
local files (cloned by git), so everything needs to be in the Docker
context. The easiest (and most stable) way to achieve this is to put the
Dockerfile into the root.
- In order to get `operator-sdk build` command fixed, I had to create a
symbolic link (of the Dockerfile) in the build directory.

Even though, this solution is not aligned with other Keycloak projects, I
believe that's the right approach. Afterall, with the shell scripts
approach we're simulating this behavior having a proper solution at hand. I
would highly encourage (and advise) adopting this approach to other
Keycloak images (such as Gatekeeper or maybe even Server).

If you don't like this solution - I prepared a workaround that fixes our
build here [7]. It's much less elegant and frankly, I don't like it.

Thanks,
Sebastian

[*] I like Peter's trick for this - he created an alias for `docker`
command pointing to `podman` !!!
[1]
https://github.com/keycloak/keycloak-operator/blob/master/build/Dockerfile
[2]
https://github.com/keycloak/keycloak-operator/blob/master/build/Dockerfile#L22
[3] https://github.com/containers/buildah/issues/1906
[4] https://github.com/keycloak/keycloak-operator/pull/96
[5] https://quay.io/repository/slaskawi/keycloak-operator-private?tab=tags
[6] https://quay.io/repository/keycloak/keycloak-operator?tab=tags
[7] https://github.com/keycloak/keycloak-operator/pull/97


More information about the keycloak-dev mailing list