Saltar al contenido

Aplicación Java 11 como imagen acoplable ligera

Hola usuario de nuestra web, encontramos la respuesta a tu interrogante, desplázate y la verás un poco más abajo.

Solución:

UPD de 07.2019: https://stackoverflow.com/a/57145029/907576

Tomando como ejemplo la aplicación de arranque de primavera simple (con solo un punto final REST) ​​hasta ahora, pude descubrir las siguientes soluciones (considerando que el contenedor de la aplicación se encuentra en build/libs/spring-boot-demo.jar antes de la compilación de Docker:

  1. Camino Jedi si queremos usar distribución oficial de Oracle OpenJDK en una versión delgada estable de Linux (Debian 9 "Stretch" por ahora):

    • usar debian:stretch-slim (última imagen estable) base
    • usar la compilación de múltiples etapas de Docker

      1. Primera etapa de compilación de Docker:

        • Descargar e instalar Oracle OpenJDK archivo en la primera etapa de compilación de Docker
        • compile la distribución mínima de Java para su proyecto (también conocido como JRE) usando jlink herramienta
      2. Segunda etapa de compilación de Docker:

        • copiar la distribución mínima compilada de Java desde la etapa 1 a la nueva imagen
        • configurar la ruta para acceder a Java
        • copiar el tarro de la aplicación a la imagen

    Entonces, final Dockerfile se ve algo así

    (actualizar JDK VERSION, URL y HASH valor):

    # First stage: JDK 11 with modules required for Spring Boot
    FROM debian:stretch-slim as packager
    
    # source JDK distribution names
    # update from https://jdk.java.net/java-se-ri/11
    ENV JDK_VERSION="11.0.1"
    ENV JDK_URL="https://download.java.net/java/GA/jdk11/13/GPL/openjdk-$JDK_VERSION_linux-x64_bin.tar.gz"
    ENV JDK_HASH="7a6bb980b9c91c478421f865087ad2d69086a0583aeeb9e69204785e8e97dcfd"
    ENV JDK_HASH_FILE="$JDK_ARJ_FILE.sha2"
    ENV JDK_ARJ_FILE="openjdk-$JDK_VERSION.tar.gz"
    # target JDK installation names
    ENV OPT="/opt"
    ENV JKD_DIR_NAME="jdk-$JDK_VERSION"
    ENV JAVA_HOME="$OPT/$JKD_DIR_NAME"
    ENV JAVA_MINIMAL="$OPT/java-minimal"
    
    # downlodad JDK to the local file
    ADD "$JDK_URL" "$JDK_ARJ_FILE"
    
    # verify downloaded file hashsum
    RUN  
            echo "Verify downloaded JDK file $JDK_ARJ_FILE:" && 
            echo "$JDK_HASH $JDK_ARJ_FILE" > "$JDK_HASH_FILE" && 
            sha256sum -c "$JDK_HASH_FILE" ; 
        
    
    # extract JDK and add to PATH
    RUN  
            echo "Unpack downloaded JDK to $JAVA_HOME/:" && 
            mkdir -p "$OPT" && 
            tar xf "$JDK_ARJ_FILE" -C "$OPT" ; 
        
    ENV PATH="$PATH:$JAVA_HOME/bin"
    
    RUN  
            java --version ; 
            echo "jlink version:" && 
            jlink --version ; 
        
    
    # build modules distribution
    RUN jlink 
        --verbose 
        --add-modules 
            java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument 
            # java.naming - javax/naming/NamingException
            # java.desktop - java/beans/PropertyEditorSupport
            # java.management - javax/management/MBeanServer
            # java.security.jgss - org/ietf/jgss/GSSException
            # java.instrument - java/lang/instrument/IllegalClassFormatException
        --compress 2 
        --strip-debug 
        --no-header-files 
        --no-man-pages 
        --output "$JAVA_MINIMAL"
    
    # Second stage, add only our minimal "JRE" distr and our app
    FROM debian:stretch-slim
    
    ENV JAVA_HOME=/opt/java-minimal
    ENV PATH="$PATH:$JAVA_HOME/bin"
    
    COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
    COPY "build/libs/spring-boot-demo.jar" "/app.jar"
    
    EXPOSE 8080
    CMD [ "-jar", "/app.jar" ]
    ENTRYPOINT [ "java" ]
    

    Nota:

    • hay 5 módulos java incluidos en el ejemplo mínimo de JRE (java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument). Los encontré “manualmente” ejecutando la aplicación y arreglando ClassNotFoundException. Esperando algunas recomendaciones / guías adicionales de los desarrolladores de Spring Boot qué módulos de Java incluir y cuándo, al igual que eliminar algunas dependencias redundantes, como java.desktop, que parece usarse solo para PropertyEditorSupport
    • Si tiene miedo de perder algunos módulos, son bastante livianos y todos juntos aumentan el tamaño de aproximadamente 2 MB. Obtenga una lista completa de java.* y jdk.* 11 módulos:

      java --list-modules | grep -E "^java.[^@]*" | cut -d @ -f 1
      java --list-modules | grep -E "^jdk.[^@]*" | cut -d @ -f 1

    El tamaño de la imagen resultante en mi caso fue 123 MB con un mínimo de 7 módulos Spring Boot y 125 MB con toda java.* modulos

    Como una mejora opcional de este flujo de trabajo de compilación:

    • Construya previamente una imagen con JDK descargado y extraído y utilícela como imagen base para la primera etapa
    • si sabe qué módulos incluir cada vez, cree previamente una imagen base con JRE mínimo compilado y módulos incluidos
  2. Manera fácil con distribuciones Open JDK del proveedor:

    Frente a Zulu JDK 11 de Oracle Azul es compatible con el puerto Alpine y tiene la imagen de Docker base respectiva.

Por lo tanto, si se respeta Zulu JVM / JDK, la compilación de Docker es mucho más simple:

FROM azul/zulu-openjdk-alpine:11 as packager

RUN  
        java --version ; 
        echo "jlink version:" && 
        jlink --version ; 
    

ENV JAVA_MINIMAL=/opt/jre

# build modules distribution
RUN jlink 
    --verbose 
    --add-modules 
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument 
        # java.naming - javax/naming/NamingException
        # java.desktop - java/beans/PropertyEditorSupport
        # java.management - javax/management/MBeanServer
        # java.security.jgss - org/ietf/jgss/GSSException
        # java.instrument - java/lang/instrument/IllegalClassFormatException
    --compress 2 
    --strip-debug 
    --no-header-files 
    --no-man-pages 
    --output "$JAVA_MINIMAL"

# Second stage, add only our minimal "JRE" distr and our app
FROM alpine

ENV JAVA_MINIMAL=/opt/jre
ENV PATH="$PATH:$JAVA_MINIMAL/bin"

COPY --from=packager "$JAVA_MINIMAL" "$JAVA_MINIMAL"
COPY "build/libs/spring-boot-demo.jar" "/app.jar"

EXPOSE 8080
CMD [ "-jar", "/app.jar" ]
ENTRYPOINT [ "java" ]

La imagen resultante es 73 MB, como se esperaba con distribuciones de Alpine despojadas.

A 07.2019

(Nota: la imagen de la primera etapa podría ser como grasa como desee: se puede usar debian / ubuntu / lo que sea e incluir git / gradle / lo que sea; esto no influirá en el tamaño final de la imagen resultante, que se basa completamente en la última (segunda) etapa)

Uso del repositorio de la comunidad Alpine

FROM alpine:latest as packager

RUN apk --no-cache add openjdk11-jdk openjdk11-jmods

ENV JAVA_MINIMAL="/opt/java-minimal"

# build minimal JRE
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink 
    --verbose 
    --add-modules 
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument 
    --compress 2 --strip-debug --no-header-files --no-man-pages 
    --release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE" 
    --output "$JAVA_MINIMAL"

FROM alpine:latest

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

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY build/libs/application.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

Usando AdoptOpenJDK

FROM adoptopenjdk/openjdk11:x86_64-alpine-jdk-11.0.4_11 as packager

ENV JAVA_MINIMAL="/opt/java-minimal"

# build minimal JRE
RUN jlink 
    --verbose 
    --add-modules 
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument 
    --compress 2 --strip-debug --no-header-files --no-man-pages 
    --output "$JAVA_MINIMAL"

FROM alpine:latest

# magic to make Java binaries work in Alpine
# https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/11/jdk/alpine/Dockerfile.hotspot.releases.slim#L24-L54
RUN apk 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" 
    && GCC_LIBS_URL="https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-9.1.0-2-x86_64.pkg.tar.xz" 
    && GCC_LIBS_SHA256="91dba90f3c20d32fcf7f1dbe91523653018aa0b8d2230b00f822f6722804cf08" 
    && ZLIB_URL="https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.11-3-x86_64.pkg.tar.xz" 
    && ZLIB_SHA256=17aede0b9f8baa789c5aa3f358fbf8c68a5f1228c5e6cba1a5dd34102ef4d4e5 
    && curl -LfsS https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub 
    && SGERRAND_RSA_SHA256="823b54589c93b02497f1ba4dc622eaef9c813e6b0f0ebbb2f771e32adf9f4ef2" 
    && echo "$SGERRAND_RSA_SHA256 */etc/apk/keys/sgerrand.rsa.pub" | sha256sum -c - 
    && curl -LfsS $ALPINE_GLIBC_REPO/$GLIBC_VER/glibc-$GLIBC_VER.apk > /tmp/glibc-$GLIBC_VER.apk 
    && apk add /tmp/glibc-$GLIBC_VER.apk 
    && curl -LfsS $ALPINE_GLIBC_REPO/$GLIBC_VER/glibc-bin-$GLIBC_VER.apk > /tmp/glibc-bin-$GLIBC_VER.apk 
    && apk add /tmp/glibc-bin-$GLIBC_VER.apk 
    && curl -Ls $ALPINE_GLIBC_REPO/$GLIBC_VER/glibc-i18n-$GLIBC_VER.apk > /tmp/glibc-i18n-$GLIBC_VER.apk 
    && apk add /tmp/glibc-i18n-$GLIBC_VER.apk 
    && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true 
    && echo "export LANG=$LANG" > /etc/profile.d/locale.sh 
    && curl -LfsS $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 -LfsS $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 --purge .build-deps glibc-i18n 
    && rm -rf /tmp/*.apk /tmp/gcc /tmp/gcc-libs.tar.xz /tmp/libz /tmp/libz.tar.xz /var/cache/apk/*

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

COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY build/libs/application.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

Lea también https://blog.gilliard.lol/2018/11/05/alpine-jdk11-images.html

una lista de imágenes jdk 11 por tamaño

openjdk:11.0.6-jre-buster
openjdk:11.0.6-jre
openjdk:11.0.6-jre-slim-buster
openjdk:11.0.6-jre-slim
openjdk:11.0.6-jre-stretch
adoptopenjdk:11.0.6_10-jre-openj9-0.18.1
adoptopenjdk:11.0.6_10-jre-hotspot
adoptopenjdk:11.0.6_10-jre-openj9-0.18.1-bionic
adoptopenjdk:11.0.6_10-jre-hotspot-bionic
adoptopenjdk/openjdk11:jre-11.0.6_10-ubuntu
adoptopenjdk/openjdk11:jre-11.0.6_10
adoptopenjdk/openjdk11:jre-11.0.6_10-ubi-minimal
adoptopenjdk/openjdk11:jre-11.0.6_10-ubi
adoptopenjdk/openjdk11:jre-11.0.6_10-debianslim
adoptopenjdk/openjdk11:jre-11.0.6_10-debian
adoptopenjdk/openjdk11:jre-11.0.6_10-centos
adoptopenjdk/openjdk11:jre-11.0.6_10-alpine
adoptopenjdk/openjdk11:x86_64-alpine-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-debian-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-debianslim-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubi-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubi-minimal-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-centos-jre-11.0.6_10
adoptopenjdk/openjdk11:x86_64-ubuntu-jre-11.0.6_10
mcr.microsoft.com/java/jre:11u6-zulu-alpine
mcr.microsoft.com/java/jre:11u6-zulu-centos
mcr.microsoft.com/java/jre:11u6-zulu-debian8
mcr.microsoft.com/java/jre:11u6-zulu-debian9
mcr.microsoft.com/java/jre:11u6-zulu-debian10
mcr.microsoft.com/java/jre:11u6-zulu-ubuntu
azul/zulu-openjdk-alpine:11.0.6-jre

imagenes

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *