[JAVA] Comment réduire l'image de Spring Boot Docker

emballer

AdoptOpenJDK AdoptOpenJDK-Alpine Custom Runtime
436 MB 358 MB 85.5 MB

Exemple de code

Étape ① Obtenez le module requis avec jdeps

Utilisez la commande jdeps pour savoir de quels modules dépend l'application Spring Boot.

Cependant, lorsque je vérifie le fichier jar exécutable de SpringBoot avec jdeps, seuls java.base et java.logging sont générés, et ce JRE seul ne démarre pas SpringBoot. Par conséquent, utilisez le script Shell présenté sur le site suivant pour obtenir les modules dépendants.

#!/bin/sh
# jdeps-spring-boot

set -eu

readonly TARGET_JAR=$1
readonly TARGET_VER=$2

#Répertoire pour extraire le jar
readonly TMP_DIR="/tmp/app-jar"
mkdir -p ${TMP_DIR}
trap 'rm -rf ${TMP_DIR}' EXIT

#Pot d'extrait
unzip -q "${TARGET_JAR}" -d "${TMP_DIR}"

#production
jdeps \
    -classpath \'${TMP_DIR}/BOOT-INF/lib/*:${TMP_DIR}/BOOT-INF/classes:${TMP_DIR}\' \
    --print-module-deps \
    --ignore-missing-deps \
    --module-path ${TMP_DIR}/BOOT-INF/lib/javax.activation-api-1.2.0.jar \
    --recursive \
    --multi-release ${TARGET_VER} \
    -quiet \
    ${TMP_DIR}/org ${TMP_DIR}/BOOT-INF/classes ${TMP_DIR}/BOOT-INF/lib/*.jar

Lorsque le nom de fichier du script Shell est get-springboot-module.sh, exécutez comme suit.

./get-springboot-module.sh <Pot SpringBoot> <Java Version>

Exemple d'exécution:

./get-springboot-module.sh demo-0.0.1-SNAPSHOT.jar 11

Les modules requis pour le résultat de l'exécution sont sortis.

java.base,java.desktop,java.instrument,java.management.rmi,java.naming,java.prefs,java.scripting,java.security.jgss,java.sql,jdk.httpserver,jdk.unsupported

point important

Lorsque vous exécutez . / Get-springboot-module.sh, exécutez-le sur Java 12 ou supérieur.

C'est parce que Java 11 a un bogue qui provoque une NullPointerException lors de la tentative d'analyse d'une classe qui n'existe pas lors de l'analyse de javafx.media. Pour éviter cela, vous devez spécifier --ignore-missing-deps, qui a été ajouté à partir de Java 12.

--Référence: [Obtenir un NPE sur l'outil jdeps Java 11 lors de l'analyse des fichiers .jar Spring Boot](https://stackoverflow.com/questions/59284163/getting-a-npe-on-java-11-jdeps-tool-when -scanning-spring-boot-jar-files)

Étape ② Créez un JRE personnalisé

--Préparez le Dockerfile suivant. --Dans jlink --add-modules, décrivez la sortie des modules à l'étape ①.

FROM adoptopenjdk/openjdk11:alpine AS java-build
WORKDIR /jlink
ENV PATH $JAVA_HOME/bin:$PATH
RUN jlink --strip-debug --no-header-files --no-man-pages --compress=2 --module-path $JAVA_HOME \
    --add-modules java.base,java.desktop,java.instrument,java.management.rmi,java.naming,java.prefs,java.scripting,java.security.jgss,java.sql,jdk.httpserver,jdk.unsupported \
    --output jre-min

Étape ③ Démarrez SpringBoot sur le JRE personnalisé à l'aide de la construction en plusieurs étapes

--Ajoutez le Dockerfile préparé à l'étape ②.

FROM adoptopenjdk/openjdk11:alpine AS java-build
WORKDIR /jlink
ENV PATH $JAVA_HOME/bin:$PATH
RUN jlink --strip-debug --no-header-files --no-man-pages --compress=2 --module-path $JAVA_HOME \
    --add-modules java.base,java.desktop,java.instrument,java.management.rmi,java.naming,java.prefs,java.scripting,java.security.jgss,java.sql,jdk.httpserver,jdk.unsupported \
    --output jre-min


FROM alpine:3.12.0
USER root

RUN apk --update add --no-cache ca-certificates curl openssl binutils xz \
    && GLIBC_VER="2.28-r0" \
    && ALPINE_GLIBC_REPO="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \
    && GCC_LIBS_URL="https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-8.2.1%2B20180831-1-x86_64.pkg.tar.xz" \
    && GCC_LIBS_SHA256=e4b39fb1f5957c5aab5c2ce0c46e03d30426f3b94b9992b009d417ff2d56af4d \
    && ZLIB_URL="https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.9-1-x86_64.pkg.tar.xz" \
    && ZLIB_SHA256=bb0959c08c1735de27abf01440a6f8a17c5c51e61c3b4c707e988c906d3b7f67 \
    && curl -Ls https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -Ls ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-${GLIBC_VER}.apk > /tmp/${GLIBC_VER}.apk \
    && apk add /tmp/${GLIBC_VER}.apk \
    && curl -Ls ${GCC_LIBS_URL} -o /tmp/gcc-libs.tar.xz \
    && echo "${GCC_LIBS_SHA256}  /tmp/gcc-libs.tar.xz" | sha256sum -c - \
    && mkdir /tmp/gcc \
    && tar -xf /tmp/gcc-libs.tar.xz -C /tmp/gcc \
    && mv /tmp/gcc/usr/lib/libgcc* /tmp/gcc/usr/lib/libstdc++* /usr/glibc-compat/lib \
    && strip /usr/glibc-compat/lib/libgcc_s.so.* /usr/glibc-compat/lib/libstdc++.so* \
    && curl -Ls ${ZLIB_URL} -o /tmp/libz.tar.xz \
    && echo "${ZLIB_SHA256}  /tmp/libz.tar.xz" | sha256sum -c - \
    && mkdir /tmp/libz \
    && tar -xf /tmp/libz.tar.xz -C /tmp/libz \
    && mv /tmp/libz/usr/lib/libz.so* /usr/glibc-compat/lib \
    && apk del binutils \
    && rm -rf /tmp/${GLIBC_VER}.apk /tmp/gcc /tmp/gcc-libs.tar.xz /tmp/libz /tmp/libz.tar.xz /var/cache/apk/*

COPY --from=java-build /jlink/jre-min /opt/jre-min
COPY ./demo-0.0.1-SNAPSHOT.jar /opt/demo/demo-0.0.1-SNAPSHOT.jar
ENV PATH /opt/jre-min/bin:$PATH

EXPOSE 8080
WORKDIR /
CMD ["java", "-jar", "/opt/demo/demo-0.0.1-SNAPSHOT.jar"]

Courir

docker build -t demo-official-openjdk-custom-runtime:latest .

--Confirmez que l'image est créée

docker images

REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
demo-official-openjdk-custom-runtime   latest              49049142374f        About an hour ago   85.5MB

--Confirmez qu'il démarre avec la commande suivante.

docker run -d -p 8080:8080 --name demo-official-openjdk-custom-runtime demo-official-openjdk-custom-runtime:latest

Autres références

Recommended Posts

Comment réduire l'image de Spring Boot Docker
Comment configurer Spring Boot + PostgreSQL
Comment utiliser ModelMapper (Spring boot)
Créer une image Spring Boot + Docker avec Gradle
Comment diviser un fichier de message Spring Boot
Comment faire coexister CsrfRequestDataValueProcessor et RequestDataValueProcessor original sur Spring Boot
Comment utiliser MyBatis2 (iBatis) avec Spring Boot 1.4 (Spring 4)
Comment utiliser h2db intégré avec Spring Boot
Comment utiliser les attributs de session Spring Boot (@SessionAttributes)
Comment installer Docker
Comment ajouter un chemin de classe dans Spring Boot
Comment faire un pot ombré
Comment donner votre image à quelqu'un avec Docker
Comment se lier avec un fichier de propriétés dans Spring Boot
[Spring Boot] Comment se référer au fichier de propriétés
Spring Boot - Comment définir le délai d'expiration de la session
Comment rendre une image partiellement transparente avec le traitement
Comment définir l'injection de dépendance Spring Boot (DI)
Comment écrire un test unitaire pour Spring Boot 2
Comment déployer à partir d'une image Docker locale vers Heroku
Comment créer un projet Spring Boot dans IntelliJ
[Spring Boot] Comment créer un projet (pour les débutants)
Comment utiliser CommandLineRunner dans Spring Batch of Spring Boot
Comment démarrer par environnement avec Spring Boot de Maven
Essayez Spring Boot de 0 à 100.
Java - Comment créer JTable
Introduction à Spring Boot ① ~ DI ~
Comment définir nginx de Docker
Introduction à Spring Boot ② ~ AOP ~
Spring Boot à partir de Docker
Construction de l'environnement Docker × Spring Boot
Introduction à Spring Boot, partie 1
[Rails] Comment faire des graines
Écrivons comment créer une API avec SpringBoot + Docker à partir de 0
Comment modifier la valeur de paramètre de application.properties au moment du démarrage dans Spring Boot
Comment appeler et utiliser l'API en Java (Spring Boot)
[Notes personnelles] Comment pousser une image Docker vers des packages GitHub
Comment contrôler les transactions dans Spring Boot sans utiliser @Transactional
Comment utiliser Lombok au printemps
Remarques sur l'utilisation de Spring Data JDBC
Comment créer un conteneur Java
[Comment installer Spring Data Jpa]
Migrer l'image Docker vers un autre serveur
Comment créer un pilote JDBC
Pour exécuter JavaFX sur Docker
Comment créer un écran de démarrage
Comment créer un plug-in Jenkins
Mise à niveau de la botte à ressort de la série 1.5 à la série 2.0
Comment faire un projet Maven
Comment créer un tableau Java
[Android] Comment créer un fragment de dialogue
Comment créer CloudStack à l'aide de Docker
Comment démarrer Camunda avec Docker
Comment créer votre propre contrôleur correspondant à / error avec Spring Boot
Image de l'application Spring Boot à l'aide de jib-maven-plugin et lancez-la avec Docker
Comment recadrer une image avec libGDX