Search for a small container image for Java 12 Micro-services

Java 12 is GA from March 2019. Java 12 does not support Alpine Linux

Alex Punnen
Techlogs
4 min readApr 9, 2019

--

Java 12 does not support Alpine Linux. You can see the message below in the JDK 12 release page.

The Alpine Linux build previously available on this page was removed as of JDK 12 GA. It’s not production-ready because it hasn’t been tested thoroughly enough to be considered a GA build. Please use the early-access JDK 13 Alpine Linux build in its place — https://jdk.java.net/12/

Strange, this was the same message for Java 11 and we were waiting for Java 12 release to solve this and to upgrade.

The Alpine Linux build previously available on this page was removed as of JDK 11 GA. It’s not production-ready because it hasn’t been tested thoroughly enough to be considered a GA build. Please use the early-access JDK 12 Alpine Linux build in its place. https://jdk.java.net/11/

Hopefully, in Java 13 we may have the full support for Alpine Linux. But waiting another six months is no more practical. So we need to find another way to reduce the container image size.

First — Why Alpine Linux as Docker Image base for Java/other languages?

  1. Small Image Size
  2. Small Image Size == Less extra packages == Smaller Attack Surface/Lesser warnings from Docker Image Scanners

Java 8 was the last release that supported Alpine — this is the reference size

openjdk       8u201-alpine    88d1c219f815     105MB

Let us see how the alternate JDK 12 versions which is smaller than oracles container image fare, relative to the above.

adoptopenjdk/openjdk12   x86_64-alpine-jre-12.33    5c3c5120d8d0   155MB
openjdk 12-oraclelinux7 b1fc416d936f 470MB

The Open-sourced Oracle (Opensource and Oracle sound odd right?. However they release openjdk binaries) weights in at 470 MB. Too heavy!

The other option we may have is the Java 12 version of Googles slim/’distroless’ images. The Java 11 version of this weighs in at 194 MB and more than size it may have lesser attack surface; the othe option is the libc ported version of Alpine Linux.

gcr.io/distroless/java e9c8abbdb7df        49 years ago        194MB

Can I continue with Java 8 or even Java 11 ?

Yes, you can, but chances are your security architect is not going to let you. It seems Oracle will provide updates to the latest version of Java. That is Java 12.

Reason 1: Public updates of JDK 8 will end in January of 2019.

Reason 2: Security patches and bug fixes will only be contributed in source form to the latest version of the OpenJDK. Oracle will not contribute back-ported updates to older versions of OpenJDK. Oracle’s approach is that this work can be undertaken by the broader Java community if there is a demand for it

Ref — https://www.azul.com/eliminating-java-update-confusion/ + similar blogs from Azul ( which are informative + plug to make you purchase from Azul — https://www.azul.com/products/zulu-enterprise/ )

Java 8 is dated. I see new GC announced in Java 12. Plus I guess many more. Have been a Java developer for many years. But I guess I will never select Java for a new project or micro-service (and that was my view for about 2 years now). These strict licensing from Oracle and lack of updates etc will drive more people to better languages like Go lang (which is climbing up the Tiobe index — pretty impressive for a new language to be in top 20, especially one that is not that simple in its syntax)

So what are the options now to move to OpenJDK 1 ?

If you are wondering how Alpine Linux different from other Linux ; basically, it used musl whereas most of the other common distro uses libc

Option 1 — Forget about the size; Use OpenJDK 12

You can see the tags here -https://docs.docker.com/samples/library/openjdk/

Example tag — 12-jdk-oraclelinux7 — (There is no JRE folder )
Dockerfile

Docker imageopenjdk  12-oraclelinux7  b1fc416d936f  10 days ago         470MB#Inside the container 
bash-4.2# java -version
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

Option 2 — Use Alpine Linux as a base (and glibc port for Alpine Linux)

You can see the tags here -https://hub.docker.com/r/adoptopenjdk/openjdk12

Example tag x86_64-alpine-jre-12.33 — Docker file.

(You can see the GLIBC package provided by @sgerrand used here)

RUN apk --update add --no-cache --virtual .build-deps curl binutils \    && GLIBC_VER="2.29-r0" \    && ALPINE_GLIBC_REPO="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \

The image size is still pretty less 155 MB

Docker image 
adoptopenjdk/openjdk12 x86_64-alpine-jre-12.33 5c3c5120d8d0 37 hours ago 155MB
# Inside the container
docker run -it --rm adoptopenjdk_alpine:12 /bin/ash
/ # java -version
Picked up JAVA_TOOL_OPTIONS:
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment AdoptOpenJDK (build 12+33)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 12+33, mixed mode, sharing)

Option 3 -Use Googles ‘Distroless’ option (when there is an image for Java 12)

This is basically a stripped down linux base https://github.com/GoogleContainerTools/distroless/tree/master/base

This image contains a minimal Linux, glibc-based system. It is intended for use directly by "mostly-statically compiled" languages like Go, Rust or D.

Plus the Openjdk parts

I took the Java 11 version and it is slightly bigger in size than the Alpine Linux part. But need to run Clair or security scan to check if the packages installed are more secure than the AdoptJDK based container (when Java 12 arrives)

myapp_openjdk_distroless  latest  80efb4be1c22  15 minutes ago      194MB
#Docker file
FROM gcr.io/distroless/java:11
COPY target/daas-testapp-1.0-SNAPSHOT.jar .CMD ["daas-testapp-1.0-SNAPSHOT.jar"]

References

Side note

If you are into Java then you should maybe check JIB project out. It sounds cool. I have not used it

--

--

Alex Punnen
Techlogs

SW Architect/programmer- in various languages and technologies from 2001 to now. https://www.linkedin.com/in/alexpunnen/