[JAVA] Comment créer une petite image docker de l'application openjdk 11 (EA) (1 Go → 85 Mo)

Introduction This is a translation of the following document into English. Étant donné que l'image dokcer (1 Go) d'OpenJDK11 est grande, créez une petite image (85 Mo) avec linux alpin + jlink

I am not good at English. I would be happy if you point out some strange sentences.

Goal The goal is to reduce the file size of the docker image of the java application.

I will create an environment that moves the following.

Result

The size of 1 GB has been reduced to about 85 MB. Image size is the result output by the docker images command.

image type jlink size
openjdk:11-jdk not used 1GB
openjdk:11-jdk used 468MB
hirokimatsumoto/alpine-openjdk-11 not used 336MB
hirokimatsumoto/alpine-openjdk-11 used 84.6MB

hirokimatsumoto/alpine-openjdk-11 is https://hub.docker.com/r/hirokimatsumoto/alpine-openjdk-11/ openjdk is https://hub.docker.com/_/openjdk/

Background problem The docker image of openjdk 11 is published in the official respoitory of docker hub. https://hub.docker.com/_/openjdk/

This image has the following problem.

The file size was confirmed with the following command.

$ sudo docker images |grep jdk
docker.io/openjdk                            11-jdk   f684efd78557  2 weeks ago         979 MB
$

I confirmed that libjvm.so becomes larger when using jlink.

$ docker run -it --rm openjdk:11-jdk /bin/sh
# ls -l /usr/lib/jvm/java-11-openjdk-amd64/lib/server/
total 34944
-rw-r--r-- 1 root root     1322 Jul 27 03:41 Xusage.txt
-r--r--r-- 1 root root 18210816 Jul 27 22:22 classes.jsa
-rw-r--r-- 1 root root    14440 Jul 27 03:41 libjsig.so
-rw-r--r-- 1 root root 17551048 Jul 27 03:41 libjvm.so
# jlink \
     --module-path /opt/java/jmods \
     --compress=2 \
     --add-modules java.base,java.logging,jdk.jfr  \
     --no-header-files \
     --no-man-pages \
     --output /opt/jdk-11-mini-runtime
#  ls -l /opt/jdk-11-mini-runtime/lib/server/
total 414452
-rw-r--r-- 1 root root      1322 Aug 14 09:41 Xusage.txt
-rw-r--r-- 1 root root     25384 Aug 14 09:41 libjsig.so
-rw-r--r-- 1 root root 424362808 Aug 14 09:41 libjvm.so
#

The generated libjvm.so increased to 424 MB. This problem is probably part of the following issue issue. https://github.com/docker-library/openjdk/issues/217

How to build small image

  1. Create an environment that uses jlink on alpine linux

https://hub.docker.com/r/hirokimatsumoto/alpine-openjdk-11/

FROM alpine:3.8

RUN mkdir /opt; cd /opt; \
    wget https://download.java.net/java/early_access/alpine/25/binaries/openjdk-11-ea+25_linux-x64-musl_bin.tar.gz \
    && tar zxf openjdk-11-ea+25_linux-x64-musl_bin.tar.gz \
    && ln -s jdk-11 java \
    && rm -f openjdk-11-ea+25_linux-x64-musl_bin.tar.gz

ENV JAVA_HOME=/opt/java
ENV PATH="$PATH:$JAVA_HOME/bin"

I should use checksum, but it is not.

  1. Build Application Image using jlink.

The target application is https://github.com/h-r-k-matsumoto/k8s-jmc-sample

FROM hirokimatsumoto/alpine-openjdk-11:latest as jlink-package
# First: generate java runtime module by jlink.

RUN jlink \
     --module-path /opt/java/jmods \
     --compress=2 \
     --add-modules jdk.jfr,jdk.management.agent,java.base,java.logging,java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
     --no-header-files \
     --no-man-pages \
     --output /opt/jdk-11-mini-runtime

# Second: generate run image.
FROM alpine:3.8

ENV JAVA_HOME=/opt/jdk-11-mini-runtime
ENV PATH="$PATH:$JAVA_HOME/bin"

COPY --from=jlink-package /opt/jdk-11-mini-runtime /opt/jdk-11-mini-runtime
COPY target/k8s-jmc-sample-0.1.0-SNAPSHOT.jar /opt/spring-boot/

EXPOSE 30001 7199
CMD java \
    -XX:StartFlightRecording=name=sample,filename=/spring-boot/jfr/sample.jfr,delay=30s,maxage=2h,maxsize=10m,dumponexit=true,settings=/spring-boot/config/profile.jfc \
    -Dcom.sun.management.jmxremote.port=7199 \
    -Dcom.sun.management.jmxremote.rmi.port=7199 \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -jar /opt/spring-boot/k8s-jmc-sample-0.1.0-SNAPSHOT.jar \
    --server.port=${SPRING_SERVER_PORT} \
    --spring.config.location=/spring-boot/config/application.yaml
$ mvn clean package
$ docker build  -t  gcr.io/prod-bl-cloud/k8s-jmc-sample:java11-mini-runtime .
  1. Deploy Rewrite the kubernetes configuration file and deploy it.
$ kubectl apply -f kubernetes

Reference

Recommended Posts

Comment créer une petite image docker de l'application openjdk 11 (EA) (1 Go → 85 Mo)
Comment déployer à partir d'une image Docker locale vers Heroku
Comment créer une méthode
Comment créer une image de conteneur légère pour les applications Java
[Notes personnelles] Comment pousser une image Docker vers des packages GitHub
Préparation à la création de l'application Rails
Utilisez Jenkins pour créer dans Docker, puis créez une image Docker.
Comment créer un référentiel Maven pour 2020
[Docker] Comment créer un environnement virtuel pour les applications Rails et Nuxt.js
[Swift5] Comment créer un écran de démarrage
[rails] Comment créer un modèle partiel
Volume d'essais pour créer une application Web Java sur Windows Server 2016
Comment migrer une application Web créée dans un environnement Docker local vers AWS
Manuel Docker Compact (4: Créer une image personnalisée)
[Introduction à Docker] Créer une image Docker pour l'apprentissage automatique et utiliser le notebook Jupyter
Comment créer une base de données H2 n'importe où
Résumé de la création de balises JSF personnalisées
[Rails] Comment créer un graphique à l'aide de lazy_high_charts
Comment obtenir un heapdump à partir d'un conteneur Docker
Comment réduire l'image de Spring Boot Docker
Comment créer des pages pour le tableau "kaminari"
Comment créer une classe qui hérite des informations de classe
Comment créer un thème dans Liferay 7 / DXP
Comment donner votre image à quelqu'un avec Docker
[1st] Comment créer un projet de framework Spring-MVC
Comment créer facilement un pull-down avec des rails
[Rails] Comment créer un bouton de partage Twitter
Comment installer Docker dans l'environnement local d'une application Rails existante [Rails 6 / MySQL 8]
J'ai essayé d'utiliser Wercker pour créer et publier une image Docker qui lance GlassFish 5
[Docker] Comment voir le contenu des volumes. Démarrez un conteneur avec les privilèges root.
J'ai créé une image Docker pour la version japonaise de SDAPS
Créer une image docker pour exécuter une application Java simple
[Introduction] Créer une application Ruby on Rails
Comment créer un environnement Java en seulement 3 secondes
Comment créer une URL JDBC (Oracle Database, Thin)
Réduction du poids de l'image Docker grâce à l'application build-React en plusieurs étapes
Comment créer un projet Spring Boot dans IntelliJ
[Spring Boot] Comment créer un projet (pour les débutants)
Comment créer un URI de données (base64) en Java
Créer un conteneur Docker pour convertir EPS en source PGF
Manipulez les pixels pour créer une image d'un ensemble de Mandelbrot
[Rails 6] Comment définir une image d'arrière-plan dans Rails [CSS]
Comment juger le clic de n'importe quelle zone de l'image
[Offre d'abonnement Apple] Comment créer une signature d'offre promotionnelle
Si vous souhaitez transformer une application Java en une image Docker, il est pratique d'utiliser jib.
Comment installer Docker
Comment créer docker-compose
Créez une image Docker avec le JDK Oracle installé (miam
Comment créer un serveur d'applications sur une instance EC2 d'AWS
Comment créer un formulaire pour sélectionner une date dans le calendrier
Comment créer une partie d'espace réservé à utiliser dans la clause IN
Comment graver un disque d'installation de Windows à partir d'Ubuntu
Une série d'étapes pour créer des livrables pour les portefeuilles avec Rails
Comment déplacer une autre classe avec une action de bouton d'une autre classe.
[Ruby] Comment récupérer le contenu du double hachage
Comment créer un portlet de générateur de services dans Liferay 7 / DXP
J'ai essayé de créer un environnement de développement padrino avec Docker