当前可用的Oracle openjdk-11映像构建未剥离的libjvm.so
模块,该模块具有数百兆字节,必须单独剥离:
所以问题是:
有哪些优化或推荐的方法来构建和交付作为docker映像的Java11应用程序?
2019.7.UPD:https://stackoverflow.com/A/57145029/907576
作为一个简单的Spring Boot应用程序(只有一个RESTendpoint)的例子,到目前为止,我已经找到了以下解决方案(考虑到应用程序jar位于Docker构建之前的build/libs/spring-boot-demo.jar
):
>
如果我们想在稳定的slim Linux版本上使用Oracle OpenJDK正式发行版(Debian9“Stretch”
)的绝地路径:
# 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" ]
java-list-modules grep-e“^java\.[^@]*”cut-d@-f 1
java-list-modules grep-e“^jdk\.[^@]*”cut-d@-f 1
在我的例子中,最小7个Spring Boot模块的结果映像大小为123 MB,所有java.*
模块的结果映像大小为125 MB
作为此生成工作流的可选改进:
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" ]
问题内容: 受问题启发,为什么Java 11基本Docker映像这么大?(openjdk:11-jre-slim)我发现Java世界中的这个话题仍然没有解决。 至于常见问题/陷阱(在上面的票证中讨论): JRE没有作为单独的“包”分发。应改用JDK的模块 Oracle OpenJDK 11不支持Linux Alpine,因此无法轻松创建 轻量级 映像 同时,当前稳定的Debian版本仍然没有Jav
一个简单的Spring Boot应用程序仅打印一个“Hello World”,当它打包为一个可部署的WAR时,它的大小为11.5MB。当我爆发战争时,WEB-INF/lib文件夹是库太多的根本原因。 如何仅使用最少的必需/依赖库创建WAR? 在提到spring-boot-starter-tomcat的作用域时,嵌入式Tomcat服务器是否仍与WAR一起打包? 我在玩Spring测试套件(STS)附
问题内容: 在创建新的ASP.NET Core MVC应用程序时,特别是在React / Redux(或其他需要Node.js的)模板上使用什么正确的Docker映像?如果不是特定的映像,对于由ASP.NET Core MVC支持的Node.js应用程序,应该在Dockerfile中遵循什么命令或过程? 除了运行支持MVC站点外,我不需要框架的SDK版本。 运行时映像未安装Node.js,在尝试运
之后,我通过以下内容开始图像: 命令提示符显示服务器已成功启动,当我试图访问web应用程序时,这也可以工作: 显示适当的HTML欢迎页。
问题内容: 是否有任何Java库允许构建没有任何应用程序服务器框架的简单独立Web服务服务器? 问题答案: Java 6包含JAX-WS,这使得在独立应用程序中托管Web服务非常容易:
主要内容:使用普通函数创建 goroutine,使用匿名函数创建goroutine在编写 Socket 网络程序时,需要提前准备一个线程池为每一个 Socket 的收发包分配一个线程。开发人员需要在线程数量和 CPU 数量间建立一个对应关系,以保证每个任务能及时地被分配到 CPU 上进行处理,同时避免多个任务频繁地在线程间切换执行而损失效率。 虽然,线程池为逻辑编写者提供了线程分配的抽象机制。但是,如果面对随时随地可能发生的并发和线程处理需求,线程池就不是非常直观和方便了。能否