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
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?
- Small Image Size
- 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:11COPY 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