Container images for the Microsoft Build of OpenJDK
This article provides information on the available container images for the Microsoft Build of OpenJDK.
We currently supply Linux-based container images for Ubuntu and Microsoft CBL-Mariner, now known as Azure Linux. The images are published in the Microsoft Artifact Registry located at mcr.microsoft.com/openjdk/jdk
.
To pull the latest image for a specific tag, use the following command:
docker pull mcr.microsoft.com/openjdk/jdk:<tag>
The following table shows the tag to use for your Linux distribution and JDK version.
Base OS | OpenJDK 21 | OpenJDK 17 | OpenJDK 11 | OpenJDK 8 |
---|---|---|---|---|
Ubuntu 22.04 | 21-ubuntu |
17-ubuntu |
11-ubuntu |
N/A |
CBL Mariner 2.0 | 21-mariner |
17-mariner |
11-mariner |
8-mariner |
CBL-Mariner 2.0 Distroless | 21-distroless |
17-distroless |
11-distroless |
8-distroless |
Note: Images for OpenJDK 8 ship with binaries of Eclipse Temurin, from the Eclipse Adoptium project.
The images above are offered for both amd64
and arm64
architectures. Your container runtime shall pull the right image based on your environment. To force a pull of an image for a specific architecture, use the following:
$ docker pull --platform=linux/arm64 mcr.microsoft.com/openjdk/jdk:21-mariner
To force an architecture inside a Dockerfile
, you may use the following:
FROM --platform=linux/arm64 mcr.microsoft.com/openjdk/jdk:21-mariner AS build
# ...
For more information on building multi-platform container images, check the documentation of your container runtime. For example, Docker and Podman.
Create a Dockerfile with the following contents:
# Example using MS Build of OpenJDK image directly
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu
# Continue with your application deployment
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
The distroless images are based on the CBL-Mariner 2.0 distribution by Microsoft. They require a different approach to deploying an application. Because the distroless images do not contain a complete Linux distribution, there is no shell, for example.
The ENTRYPOINT
of these images is already configured pointing to the java
command. Consuming Dockerfiles must use the CMD
instruction to complete the command-line arguments of the JVM launcher process.
Create a Dockerfile with the following contents:
FROM mcr.microsoft.com/openjdk/jdk:21-distroless
COPY app.jar /app.jar
CMD ["-Xmx256m", "-jar", "/app.jar"]
If you prefer to use a different OS base image distribution, you can copy the JDK from an existing pre-built image using the COPY --from
instruction in a Dockerfile, similar to the following example:
# Example using MS Build of OpenJDK image with a different base image
FROM debian:buster-slim
ENV LANG en_US.UTF-8
ENV JAVA_HOME /usr/lib/jvm/msopenjdk-21-amd64
ENV PATH "${JAVA_HOME}/bin:${PATH}"
COPY --from=mcr.microsoft.com/openjdk/jdk:21-ubuntu $JAVA_HOME $JAVA_HOME
# Continue with your application deployment
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
You can also install the JDK using either yum
or apt-get
, or simply extracting a tar.gz
file and configuring JAVA_HOME
accordingly. Read more.
To deploy Microsoft Build of OpenJDK on different versions of Ubuntu base images, Microsoft recommends that users author their own Dockerfiles
. For reference, the below Dockerfile
builds an image with Ubuntu 24.04.
# Example using MS Build of OpenJDK image with a different version of Ubuntu
FROM ubuntu:24.04
ENV LANG en_US.UTF-8
ENV JAVA_HOME /usr/lib/jvm/msopenjdk-21-amd64
ENV PATH "${JAVA_HOME}/bin:${PATH}"
COPY --from=mcr.microsoft.com/openjdk/jdk:21-ubuntu $JAVA_HOME $JAVA_HOME
# Continue with your application deployment
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
While Microsoft does not supply Alpine-based images, we do supply a limited set of musl-compiled JDK binaries for Alpine Linux.
Users are welcome to create container images for Alpine Linux using the available binaries.
Create a Dockerfile with the following contents:
FROM alpine:latest
ENV JAVA_HOME=/usr/lib/jdk
ENV PATH=${PATH}:${JAVA_HOME}/bin
# Default to UTF-8 file.encoding
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
# (Optional) Add extra packages for fontconfig and ttf-dejavu to support server-side image generation
RUN apk add --no-cache fontconfig libretls musl-locales musl-locales-lang ttf-dejavu tzdata zlib \
&& rm -rf /var/cache/apk/*
# Download and extract JDK 17
RUN wget -nv -O jdk.tar.gz https://aka.ms/download-jdk/microsoft-jdk-17-alpine-x64.tar.gz && \
mkdir $JAVA_HOME && \
tar xf jdk.tar.gz -C $JAVA_HOME --strip-components 1 --no-same-owner
# Copy the application
COPY app.jar /app.jar
CMD [ "java", "-jar", "/app.jar" ]
To create a custom Java runtime image, use a multi-stage Dockerfile similar to the following example:
# Example of custom Java runtime using jlink in a multi-stage container build
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu as runtime-build
# Create a custom Java runtime
RUN $JAVA_HOME/bin/jlink \
--add-modules java.base \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output /javaruntime
# Define your base image. You may use any base OS and version of your choice.
FROM debian:buster-slim
ENV LANG en_US.UTF-8
ENV JAVA_HOME /usr/lib/jvm/msopenjdk-21-amd64
ENV PATH "${JAVA_HOME}/bin:${PATH}"
COPY --from=runtime-build /javaruntime $JAVA_HOME
# Continue with your application deployment
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
For more information on creating custom Java runtimes, see Java Runtimes with jlink
The images come with an app
user that can be optionally enabled and used by consuming layers:
FROM mcr.microsoft.com/openjdk/jdk:21-mariner
WORKDIR /home/app
COPY japp.jar japp.jar
USER app
CMD ["java", "-jar", "/opt/app/japp.jar"]
In the above example, the application binary is copied as root
, since the images remain with root
by default. The application then is executed as app
. The folder /home/app
is also owned by user app
, giving the application a writeable filesystem.
The images for Microsoft Build of OpenJDK are configured by default with the en_US.UTF-8
locale. If you want to use a different locale, or a different base image as described previously, you'll need to manually configure environment variables in your own Dockerfile, and make sure the locale you want is installed.
For example, to use the pt_BR.UTF-8
locale on an Ubuntu-based image, you can add the following lines to your Dockerfile:
...
USER root
RUN apt-get update
RUN apt-get install -y locales
RUN sed -i '/pt_BR.UTF-8/s/^# //g' /etc/locale.gen
RUN locale-gen
ENV LANG pt_BR.UTF-8
ENV LANGUAGE pt_BR:pt
ENV LC_ALL pt_BR.UTF-8
...
This Dockerfile is provided as an example. It is not meant to suggest the most optimal configurations.
Microsoft Build of OpenJDK container images are only available under the tags listed previously. We don't supply tags for minor versions, and the major version tags always have the latest minor version to ensure that developers will have the latest update for any given major version.
These base images use the underlying package manager mechanism of the Linux distributions to install the JDK package. Therefore, to stay on a particular older version, you will need to use tools such as apt-get
or yum
to install the specific minor version of the JDK.
To rollback to specific versions on different base OS images outside the list of supplied images, for example debian:buster-slim
, you can use the same approach below either in the first stage of a muli-stage container image build, or as part of a traditional Linux package installation flow. For more information, see the Install on Ubuntu 18.04+ section of Install the Microsoft Build of OpenJDK.
For CBL-Mariner
and other OS images based on RPM/yum, see the details provided later in this article.
For Ubuntu
, and other Debian-based images, you can display all available minor versions published in the Microsoft Linux repositories, as shown in the following Bash example showing commands and output. The commands shown here assume the Microsoft Linux repository is configured, as described at Install on Ubuntu 18.04+.
$ docker run --pull=always -ti --rm mcr.microsoft.com/openjdk/jdk:11-ubuntu
root@c60eacd7dd7d:/# apt-get update
...
root@c60eacd7dd7d:/# apt-cache madison msopenjdk-11
msopenjdk-11 | 11.0.23-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.22-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.21-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.20.1-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.20-3 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.20-2 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.20-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.19-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
msopenjdk-11 | 11.0.18-1 | https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages
...
This Bash example shows how to have your image revert msopenjdk-11
to an older version, say 11.0.16-1
:
root@dd24eca5bdb3:/# java -version
openjdk version "11.0.23" 2024-04-16 LTS
OpenJDK Runtime Environment Microsoft-9394293 (build 11.0.23+9-LTS)
OpenJDK 64-Bit Server VM Microsoft-9394293 (build 11.0.23+9-LTS, mixed mode, sharing)
root@a93cd1ed8783:/# apt-get -y install -y --allow-downgrades msopenjdk-11=11.0.16-1
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
fonts-dejavu
The following NEW packages will be installed:
fonts-dejavu
The following packages will be DOWNGRADED:
msopenjdk-11
0 upgraded, 1 newly installed, 1 downgraded, 0 to remove and 0 not upgraded.
Need to get 194 MB of archives.
After this operation, 13.0 MB disk space will be freed.
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 fonts-dejavu all 2.37-2build1 [3,192 B]
Get:2 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 msopenjdk-11 amd64 11.0.16-1 [194 MB]
Fetched 194 MB in 18s (10.7 MB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package fonts-dejavu.
(Reading database ... 9151 files and directories currently installed.)
Preparing to unpack .../fonts-dejavu_2.37-2build1_all.deb ...
Unpacking fonts-dejavu (2.37-2build1) ...
dpkg: warning: downgrading msopenjdk-11 from 11.0.23-1 to 11.0.16-1
Preparing to unpack .../msopenjdk-11_11.0.16-1_amd64.deb ...
update-alternatives: using /usr/lib/jvm/msopenjdk-11-amd64/lib/jfr to provide /usr/bin/jfr (jfr) in auto mode
Unpacking msopenjdk-11 (11.0.16-1) over (11.0.23-1) ...
Setting up fonts-dejavu (2.37-2build1) ...
Setting up msopenjdk-11 (11.0.16-1) ...
To do the same thing in your Dockerfile, use the following commands:
FROM mcr.microsoft.com/openjdk/jdk:11-ubuntu
...
RUN apt-get update && \
apt-get install -y --allow-downgrades msopenjdk-11=11.0.16-1
...
This Bash example uses CBL-Mariner
based images:
root [ / ]# java -version
openjdk version "11.0.15" 2022-04-19 LTS
OpenJDK Runtime Environment Microsoft-32930 (build 11.0.15+10-LTS)
OpenJDK 64-Bit Server VM Microsoft-32930 (build 11.0.15+10-LTS, mixed mode)
root [ / ]# yum update
...
root [ / ]# yum list msopenjdk-11
Loaded plugin: tdnfrepogpgcheck
msopenjdk-11.x86_64 11.0.14+9_LTS-1 @System
msopenjdk-11.x86_64 11.0.10+9-1 packages-microsoft-com-prod
msopenjdk-11.x86_64 11.0.11+9-1 packages-microsoft-com-prod
msopenjdk-11.x86_64 11.0.12+7-1 packages-microsoft-com-prod
msopenjdk-11.x86_64 11.0.13+8_LTS-1 packages-microsoft-com-prod
msopenjdk-11.x86_64 11.0.14+9_LTS-1 packages-microsoft-com-prod
root [ / ]# yum install -y --nogpgcheck msopenjdk-11-11.0.15-1
Loaded plugin: tdnfrepogpgcheck
Downgrading:
msopenjdk-11 x86_64 11.0.15-1 mariner-official-microsoft 308.10M 183.75M
Total installed size: 308.10M
Total download size: 183.75M
msopenjdk-11 192678446 100%
Testing transaction
Running transaction
Installing/Updating: msopenjdk-11-11.0.15-1.x86_64
Removing: msopenjdk-11-11.0.23-1.x86_64
To do the same thing in your Dockerfile, use the following commands:
FROM mcr.microsoft.com/openjdk/jdk:11-mariner
...
RUN yum update && \
yum install -y --nogpgcheck msopenjdk-11-11.0.15-1
...
To ensure the highest level of security and stability, our container images are rebuilt every Monday, Wednesday, and Friday. This regular rebuild schedule enables us to promptly incorporate the latest security patches and updates.
You can expect the following benefits from this rebuild schedule:
- Timely security updates: By rebuilding the images three times a week, we ensure that any new security vulnerabilities are addressed quickly.
- Improved stability: Regular updates help maintain the stability and performance of your applications by including the latest bug fixes and improvements.
If you have any questions or encounter issues related to these updates, refer to this schedule before you open a support ticket.
For more information on our support policies, see Support roadmap for the Microsoft Build of OpenJDK.
We currently do not supply Windows-based container images.
Send us your comments, thoughts, and ideas to help us improve the Microsoft Build of OpenJDK. Visit our OpenJDK discussions page on GitHub to send us your feedback.
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.