The deployment of Java applications within containerized environments has undergone a massive shift with the maturation of OpenJDK 11. As a Long-Term Support (LTS) release, OpenJDK 11 serves as a critical foundation for countless enterprise microservices, providing a balance between modern language features and institutional stability. The process of containerizing these applications involves more than simply wrapping a JAR file in an image; it requires a deep understanding of the underlying operating system flavors, the specific build providers, and the intricate relationship between the Java Virtual Machine (JVM) and the container runtime.
From a technical perspective, the move toward OpenJDK 11 in Docker involves selecting the correct base image to balance security, image size, and runtime performance. Whether utilizing the official Docker Hub images, the specialized builds from AdoptOpenJDK, or the enterprise-grade Red Hat Universal Base Images (UBI), the developer must account for architecture compatibility—ranging from x86_64 to aarch64—and the specific requirements of the target orchestration platform, such as Kubernetes or Red Hat OpenShift. This exhaustive guide explores the multifaceted ecosystem of OpenJDK 11 Docker images, the technical nuances of their implementation, and the lifecycle management of these binaries in a modern DevOps pipeline.
The AdoptOpenJDK Ecosystem and Image Architecture
AdoptOpenJDK provides a robust set of Docker images for OpenJDK Version 11 binaries, utilizing a fully open-source set of build scripts and infrastructure. This transparency is vital for organizations that require a verifiable chain of custody for their runtime binaries. The AdoptOpenJDK images are distributed across two different DockerHub repositories, which allows users to choose between different operating system flavors while maintaining the same underlying Java binaries.
The technical implementation of these images ensures that OS-level updates are applied as fixes become available, reducing the attack surface of the container. A significant technical advantage of these images is their multi-arch support. Because the binaries are built for multiple architectures, the same Docker commands are portable across various hardware targets without requiring modification of the Dockerfile.
The following table details the specific image variants and build tags associated with the AdoptOpenJDK 11 distribution:
| OS Flavor | Build Type | Architecture Support | Dockerfile Path / Tag Example |
|---|---|---|---|
| CentOS Slim | JDK | aarch64, armv7l, ppc64le, x86_64 | jdk-11.0.11_9-centos-slim |
| CentOS | JRE | aarch64, armv7l, ppc64le, x86_64 | jre-11.0.11_9-centos |
| Debian | JDK | aarch64, armv7l, ppc64le, s390x, x86_64 | jdk-11.0.11_9-debian |
| Debian Slim | JDK | aarch64, armv7l, ppc64le, s390x, x86_64 | jdk-11.0.11_9-debian-slim |
| Debian | JRE | aarch64, armv7l, ppc64le, s390x, x86_64 | jre-11.0.11_9-debian |
| Debian Slim | JRE | aarch64, armv7l, ppc64le, s390x, x86_64 | jre-11.0.11_9-debian-slim |
For users requiring absolute version pinning to avoid breaking changes during automated deployments, AdoptOpenJDK allows the use of specific build numbers. For instance, referencing adoptopenjdk/openjdk11:jdk-11.0.9.1_1 ensures that the environment is locked to build 11.0.9.1, providing the 64-Bit Server VM in mixed mode.
Red Hat UBI and OpenShift Integration
Red Hat provides a specialized implementation of OpenJDK 11 through the Universal Base Image (UBI) framework. UBI images are OCI-compliant container base operating system images that are designed to be freely redistributable, making them ideal for commercial software distribution.
The Red Hat build of OpenJDK 11 is specifically optimized for container and serverless workloads, positioning it as a Kubernetes-native Java runtime. A primary technical distinction of the ubi8/openjdk-11 image is its integration with Source To Image (S2I) scripts. S2I is a critical component of Red Hat OpenShift, allowing developers to push raw code to a platform that automatically injects that code into a pre-configured builder image to produce a runnable container.
The technical specifications for the Red Hat OpenJDK 11 image are summarized below:
- Image Version: 1.21
- Architecture: amd64
- Maintainer: Red Hat OpenJDK [email protected]
- User: 185
- Working Directory:
/home/jboss - Exposed Ports: 8080/tcp, 8443/tcp, 8778/tcp
The use of a non-root user (UID 185) is a critical security measure. In Kubernetes and OpenShift environments, running containers as root is often prohibited by Security Context Constraints (SCC). By defaulting to a non-privileged user, the Red Hat image ensures compliance with enterprise security policies.
JVM Resource Awareness in Containerized Environments
One of the most critical technical challenges in running Java 11 in Docker is the JVM's ability to perceive container resource limits. In older versions of the JVM, the process would probe the host system for CPU cores and RAM rather than the container's allocated limits. This led to a catastrophic failure where the JVM would spawn too many garbage collector threads or allocate too much memory, resulting in the Linux Out-Of-Memory (OOM) killer terminating the process.
Inside Linux containers, OpenJDK versions 8 and later (including 11) are designed to correctly detect the container-limited number of CPU cores and available RAM. This awareness allows the JVM to adjust its internal parameters automatically, ensuring that the application remains stable within the constraints defined by the Docker --memory or --cpus flags.
Implementation Patterns for Dockerfiles
Depending on the goal—whether it is a production-ready fat-jar deployment or a development-time compilation—different Dockerfile patterns are utilized.
For a standard production deployment using an AdoptOpenJDK UBI base, the following configuration is used:
dockerfile
FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
To execute this build and run the application, the following terminal commands are required:
bash
docker build -t japp .
docker run -it --rm japp
Alternatively, for applications that require a compilation step within the container using the official openjdk:11 image, the following pattern is applied:
dockerfile
FROM openjdk:11
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", "Main"]
The build and execution sequence for this pattern is:
bash
docker build -t my-java-app .
docker run -it --rm --name my-running-app my-java-app
In scenarios where a developer needs to compile code but does not want the resulting .class files to be trapped inside a container, a volume-mount strategy is employed. This allows the host machine to retain the compiled output:
bash
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp openjdk:11 javac Main.java
In this command, -v "$PWD":/usr/src/myapp maps the current working directory to the container, and -w /usr/src/myapp sets the working directory, allowing javac to write the Main.class file directly back to the host filesystem.
Lifecycle Transition and the Shift to Eclipse Temurin
A significant shift occurred in the OpenJDK community around 2022 regarding the maintenance of project builds. Red Hat previously produced builds for Linux x8664, Linux aarch64, and Windows x8664 as a service to the community. However, a strategic decision was made to retire these "OpenJDK Project Builds" for the 11u and 8u streams.
The technical transition was marked by the cessation of builds after the July 2022 CPU update (specifically versions 11.0.16 and 8u342). The industry shifted toward Eclipse Adoptium, which produces Eclipse Temurin builds. Temurin provides a vendor-neutral, JCK-tested replacement for the community. This move ensures that the JDK 8 and JDK 11 code streams continue to receive security fixes and updates on a wider variety of platforms.
The impact for Docker users was substantial. Images tagged simply as openjdk:11 or openjdk:8 on Docker Hub became outdated by October 2022 because they lacked recent security fixes. This necessitates a migration to newer, maintained binaries such as those provided by Adoptium or the specific Red Hat UBI images.
Legal and Compliance Frameworks
The use of OpenJDK Docker images involves navigating several layers of licensing. The Dockerfiles and the associated build scripts provided by AdoptOpenJDK are licensed under the Apache License, Version 2.0. However, the software contained within the image may be subject to different terms.
- Java Trademarks: All Java-based trademarks and logos remain the property of Oracle and/or its affiliates.
- Base OS Licenses: Depending on the flavor, the image may include Bash or other utilities from the base distribution (CentOS or Debian), which carry their own respective licenses.
- User Responsibility: It is the explicit responsibility of the image user to ensure that their specific use of the image complies with all applicable licenses for the installed products.
Conclusion
The deployment of OpenJDK 11 via Docker is a sophisticated operation that requires a careful selection of the base image and an understanding of JVM-to-container interaction. The transition from generic openjdk images to specialized distributions like AdoptOpenJDK and Red Hat UBI reflects a broader industry move toward transparency, security, and architecture-specific optimization.
The technical ability of OpenJDK 11 to sense container resource limits solves the historical problem of OOM errors and CPU over-allocation, making it a viable choice for high-density Kubernetes environments. However, the retirement of certain community builds in late 2022 serves as a critical warning for DevOps engineers: relying on generic tags can lead to the deployment of insecure, outdated runtimes. The shift toward Eclipse Temurin and the use of specific build versions (e.g., jdk-11.0.9.1_1) is the only way to ensure long-term stability and security.
Ultimately, the choice between a "slim" image and a "full" image involves a trade-off between deployment speed and diagnostic capability. While slim images reduce the attack surface and decrease pull times, full images provide the tooling necessary for deep-system troubleshooting. By leveraging the OCI-compliant UBI images or the multi-arch AdoptOpenJDK binaries, enterprises can build a scalable, secure, and portable Java infrastructure.