多阶段构建jdk17-base

 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
 docker build -t jdk17-base .
[+] Building 190.1s (14/14) FINISHED                                                                                               docker:default
 => [internal] load build definition from Dockerfile                                                                                         2.2s
 => => transferring dockerfile: 3.67kB                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                            1.9s
 => => transferring context: 2B                                                                                                              0.0s
 => [internal] load metadata for docker.io/library/alpine:3.18                                                                              31.9s
 => [auth] library/alpine:pull token for registry-1.docker.io                                                                                0.0s
 => [builder 1/5] FROM docker.io/library/alpine:3.18@sha256:34871e7290500828b39e22294660bee86d966bc0017544e848dd9a255cdf59e0                15.3s
 => => resolve docker.io/library/alpine:3.18@sha256:34871e7290500828b39e22294660bee86d966bc0017544e848dd9a255cdf59e0                         1.5s
 => => sha256:34871e7290500828b39e22294660bee86d966bc0017544e848dd9a255cdf59e0 1.64kB / 1.64kB                                               0.0s
 => => sha256:d695c3de6fcd8cfe3a6222b0358425d40adfd129a8a47c3416faff1a8aece389 528B / 528B                                                   0.0s
 => => sha256:b541f2080109ab7b6bf2c06b28184fb750cdd17836c809211127717f48809858 1.47kB / 1.47kB                                               0.0s
 => => sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c 3.40MB / 3.40MB                                               8.3s
 => => extracting sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c                                                    1.0s
 => [builder 2/5] RUN set -eux;     apk add --no-cache wget tar gzip binutils;                                                              20.5s
 => [builder 3/5] RUN set -eux;     wget -O jdk.tar.gz https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/Ope  69.2s
 => [builder 4/5] RUN echo 'public class CheckEncoding { public static void main(String[] args) { System.out.println(System.getProperty("fi  4.0s
 => [builder 5/5] RUN set -eux;     MODULES=$(ls /usr/lib/jvm/java17/jmods | sed 's/.jmod$//' | grep -vE 'java.desktop|jdk.incubator.forei  20.3s
 => [stage-1 2/5] COPY --from=builder /jre /opt/java/jdk17                                                                                   3.7s
 => [stage-1 3/5] COPY --from=builder /CheckEncoding.class /CheckEncoding.class                                                              2.1s
 => [stage-1 4/5] RUN set -eux;     apk add --no-cache         ca-certificates p11-kit-trust         musl-locales musl-locales-lang          8.5s
 => [stage-1 5/5] RUN set -eux;     echo "Verifying install ...";     echo "java --version"; java --version;     echo "file.encoding:"; jav  3.3s
 => exporting to image                                                                                                                       2.9s
 => => exporting layers                                                                                                                      2.7s
 => => writing image sha256:78155512a485a0ff36735d278c72270f7c65921bb03d474ac55ebb2484eb18a2                                                 0.1s
 => => naming to docker.io/library/jdk17-base                                                                                                0.1s

~/workspace/tools/dockerfiles/jdk17-base 3m 13s

~/workspace/tools/dockerfiles/jdk17-base [ 3m13s]
👉👉👉➡️ ➡️ ➡️  docker image ls jdk17-base
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
jdk17-base   latest    78155512a485   4 hours ago   97.7MB

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 第一阶段:使用基础镜像来下载和安装JDK
FROM alpine:3.18 as builder

# 设置 JDK 下载链接、SHA256 散列值和安装目录
ARG JDK_URL='https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_alpine-linux_hotspot_17.0.9_9.tar.gz'
ARG JDK_SHA256='c2a571a56e5bd3f30956b17b048880078c7801ed9e8754af6d1e38b9176059a9'
ARG JDK_DIR=/usr/lib/jvm/java17

# 安装必要的工具 ,binutils 是使用jlink所需的工具
RUN set -eux; \
    apk add --no-cache wget tar gzip binutils;

# 下载并校验 JDK
RUN set -eux; \
    wget -O jdk.tar.gz ${JDK_URL}; \
    echo "${JDK_SHA256} *jdk.tar.gz" | sha256sum -c -; \
    mkdir -p ${JDK_DIR}; \
    tar --extract \
        --file jdk.tar.gz \
        --directory ${JDK_DIR} \
        # 去除归档中每个文件路径的第一部分,因为每个JDK压缩包都有一个不同名的根文件夹
        --strip-components 1 \
        --no-same-owner; \
    # 删除源文件,虽然这里删不删都不影响第二阶段
    rm -f jdk.tar.gz ${JDK_DIR}/lib/src.zip;

# 设置环境变量
ENV JAVA_HOME=${JDK_DIR}
ENV PATH=$JAVA_HOME/bin:$PATH

# 编译用于检查 file.encoding 的 Java 类,在第二阶段中,由于没有javac,需要提前编译
RUN echo 'public class CheckEncoding { public static void main(String[] args) { System.out.println(System.getProperty("file.encoding")); } }' > CheckEncoding.java && \
    javac CheckEncoding.java && \
    rm CheckEncoding.java

# 使用 jlink 创建自定义 JRE,扫描jmods目录添加除GUI、实验性孵化模块以外的所有模块
# 特别注意的是,如果你使用spring程序,务必保留 jdk.unsupported 模块
# 否则会导致objenesis无法跳过构造函数创建代理,从而对没有默认构造函数的BEAN引发NoSuchMethodException
# https://stackoverflow.com/questions/51332334/nosuchmethodexception-springframework-boot-autoconfigure-http-httpmessageconver
# 如果是java 21+ 应使用 compress=zip-6 https://bugs.openjdk.org/browse/JDK-8293667
RUN set -eux; \
    MODULES=$(ls ${JAVA_HOME}/jmods | sed 's/.jmod$//' | grep -vE 'java.desktop|jdk.incubator.foreign|jdk.incubator.vector' | tr '\n' ',' | sed 's/,$//') \
    && $JAVA_HOME/bin/jlink \
         --module-path ${JAVA_HOME}/jmods \
         --add-modules $MODULES \
         --strip-debug \
         --no-man-pages \
         --no-header-files \
         --compress=2 \
         --output /jre;

# 为最终镜像设置新的基础镜像
FROM alpine:3.18
# 注意第一阶段的变量无法保留到第二阶段
ARG JDK_HOME_DIR=/opt/java/jdk17

# 复制自定义 JRE 和 CheckEncoding.class 到新镜像
COPY --from=builder /jre ${JDK_HOME_DIR}
COPY --from=builder /CheckEncoding.class /CheckEncoding.class

# 设置环境变量
ENV JAVA_HOME=${JDK_HOME_DIR}
ENV PATH=$JAVA_HOME/bin:$PATH

# 添加所需软件
RUN set -eux; \
    apk add --no-cache \
        # utilities for keeping Alpine and OpenJDK CA certificates in sync
        # https://github.com/adoptium/containers/issues/293
        ca-certificates p11-kit-trust \
        # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8
        musl-locales musl-locales-lang \
        tzdata \
    ; \
    rm -rf /var/cache/apk/*;

# 设置其它环境变量
ENV TZ='Asia/Shanghai'
ENV LANG=C.UTF-8

# 检查JAVA运行环境并删除 CheckEncoding.class
RUN set -eux; \
    echo "Verifying install ..."; \
    echo "java --version"; java --version; \
    echo "file.encoding:"; java -cp / CheckEncoding | grep -q 'UTF-8'; \
    rm -f /CheckEncoding.class; \
    echo "Complete.";
Licensed under CC BY-NC-SA 4.0
最后更新于 Sep 10, 2025 02:16 UTC
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计
Caret Up