由于官方的openJDK17镜像近500MB,属于太大,不利于微服务镜像打包部署。
所以自定义基于alpine 3.18 和 openjdk 17 制作JRE镜像,构建Springboot项目镜像(JRE是java运行环境,不包含开发工具所以小)。
先看结论,一共测试了三种方式。
注意:只编译java SE平台的Jre环境在运行Springboot项目会有问题,精简过头也不行,少了依赖。
!!!推荐用jre17all,这是完整的JRE环境包,测试是完全没问题的。
- jre17se 只构建了javaSE平台模块包的JRE环境的镜像
- jre17all 构建了所有包模块的JRE环境的镜像
- jre17 直接用adoptium下载的JRE来创建的镜像
- openjdk 官方的镜像
1 2 3 4 5
| >docker images jre17se latest cd9e997465f6 7 seconds ago 81MB jre17all latest 8d7173e8cdd9 8 minutes ago 113MB jre17 latest 9c0b10d8c81d 1 hours ago 208MB openjdk 17 5f94f53bbced 2 hours ago 471MB
|
选型:
第一种直接使用已有的JRE创建镜像
这里我做了测试,直接用adoptium构建好的JRE包,去做镜像的话,最后的大小居然有200MB
。虽然比官方的OPENJDK的470MB
要小一半。但是还不够精简。
所以后面还是自已编译构建JRE包,可以直接跳到第二种方案查看<<<
首先创建一个目录,将下载的Jre压缩包放入。如果网络访问github正常的话,也可以直接下载
1
| wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jre_x64_alpine-linux_hotspot_17.0.9_9.tar.gz
|
创建Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| FROM alpine:3.18
COPY OpenJDK17U-jre_x64_alpine-linux_hotspot_17.0.9_9.tar.gz /tmp/openjdk.tar.gz
ENV JAVA_HOME=/opt/jdk ENV PATH=$JAVA_HOME/bin:$PATH
RUN echo "https://mirrors.aliyun.com/alpine/v3.18/main" > /etc/apk/repositories \ && echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
RUN apk add --no-cache fontconfig libretls ttf-dejavu tzdata \ && rm -rf /var/cache/apk/* \ && echo "Asia/Shanghai" > /etc/timezone \ && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN set -eux; \ mkdir -p "$JAVA_HOME"; \ tar --extract \ --file /tmp/openjdk.tar.gz \ --directory "$JAVA_HOME" \ --strip-components 1 \ --no-same-owner \ && rm -f /tmp/openjdk.tar.gz \ && find "$JAVA_HOME" -name '*.diz' -delete \ && find "$JAVA_HOME" -name '*.txt' -delete \ && rm -rf "$JAVA_HOME"/man \ && rm -rf "$JAVA_HOME"/legal
RUN rm -rf /var/cache/apk/* \ && rm -rf /tmp/*
CMD ["sh", "-c", "echo 'Java version:' && java -version && echo 'Current date and time:' && date"]
|
执行build,并启动容器验证
1 2
| // 执行会打印JAVA版本信息和时间信息 docker run --rm jre17
|
这种方式构建的是最全的,但是感觉还是有点大,所以还是自定义吧!
第二种自己构建JRE环境包
思路:首先用JDK包构建自定义的JRE环境包,再将JRE包制作到镜像里。需要采用Docker的多阶段构建,可以减少镜像大小。
老样子 先下载对应Alpine平台的的包,放到同级目录。如下:
Dockerfile文件内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| FROM alpine:3.18 as builder
ARG JDK_DIR=/usr/lib/jvm/java17 COPY OpenJDK17U-jdk_x64_alpine-linux_hotspot_17.0.12_7.tar.gz ./jdk.tar.gz
RUN set -eux; \ apk add --no-cache tar gzip binutils;
RUN set -eux; \ mkdir -p ${JDK_DIR}; \ tar --extract \ --file jdk.tar.gz \ --directory ${JDK_DIR} \ --strip-components 1 \ --no-same-owner;
ENV JAVA_HOME=${JDK_DIR} ENV PATH=$JAVA_HOME/bin:$PATH
RUN set -eux; \ $JAVA_HOME/bin/jlink \ --module-path ${JAVA_HOME}/jmods \ --add-modules ALL-MODULE-PATH \ --strip-debug \ --no-man-pages \ --no-header-files \ --compress=2 \ --output /jre17;
FROM alpine:3.18
ARG JDK_HOME_DIR=/opt/java/jdk17
COPY --from=builder /jre17 ${JDK_HOME_DIR}
ENV JAVA_HOME=${JDK_HOME_DIR} ENV PATH=$JAVA_HOME/bin:$PATH
ENV TZ='Asia/Shanghai' ENV LANG=C.UTF-8
RUN echo "https://mirrors.aliyun.com/alpine/v3.18/main" > /etc/apk/repositories \ && echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
RUN apk add --no-cache fontconfig libretls ttf-dejavu tzdata musl-locales musl-locales-lang ca-certificates p11-kit-trust \ && rm -rf /var/cache/apk/*
CMD ["sh", "-c", "echo 'Java version:' && java -version && echo 'Current date and time:' && date"]
|
部署并验证
执行build,并启动容器验证
1
| docker build -t jre17all .
|
1 2 3 4 5
| // 执行会打印JAVA版本信息和时间信息 docker run --rm jre17all // 打标签 上传到私有镜像仓库 docker tag jre17all registry.cn-hangzhou.aliyuncs.com/blog/jre17 docker push registry.cn-hangzhou.aliyuncs.com/blog/jre17
|
然后拿一个Springboot微服务验证一下
修改微服务Dockerfile首行的基础镜像为自定义的JRE from registry.cn-hangzhou.aliyuncs.com/blog/jre17
1 2 3 4 5 6
| FROM registry.cn-hangzhou.aliyuncs.com/blog/jre17 MAINTAINER dollcode ARG JAR_FILE COPY ${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
|