在《极简,利用Docker仅两行命令就能下载和编译OpenJDK11》一文中,我们用以下命令实现了OpenJDK11源码的编译:

docker run --rm \
-it \
-v /usr/local/work/openjdksrc:/src \
bolingcavalry/buildopenjdk11:0.0.2
1
2
3
4
今天我们就来看下Docker镜像bolingcavalry/buildopenjdk11:0.0.2的制作过程,看看它做了哪些事情来简化下载过程;

参考文章
如果您打算在真实Linxu环境下编译OpenJDK11源码,可以参照《Ubuntu环境编辑OpenJDK11源码》;

环境信息
操作系统:Ubuntu 16.04.5 LTS;
Docker:18.06.1-ce;
准备材料
本次镜像用到了以下材料:

Dockerfile:制作Docker镜像的脚本文件;
cmd.sh:容器启动后执行的命令脚本;
jdk10安装包,在编译OpenJDK11的时候,需要先装好jdk10作为bootjdk;
source.list:linux源;
您可以选择直接从GitHub下载上述所有内容,地址和链接信息如下表所示:

名称    链接    备注
项目主页    https://github.com/zq2599/buildopenjdk11    该项目在GitHub上的主页
git仓库地址(https)    https://github.com/zq2599/buildopenjdk11.git    该项目源码的仓库地址,https协议
git仓库地址(ssh)    git@github.com:zq2599/buildopenjdk11.git    该项目源码的仓库地址,ssh协议
要注意的问题
jdk10安装文件jdk-10_linux-x64_bin_ri.tar.gz有186兆,因此做成的镜像也很大,用户下载镜像时,一旦网络问题下载失败,docker会自动重试,此时是重新下载,这意味着之前的下载都白做了,为了缓解这个问题,可以把文件分割成多个小文件,这样虽然整体大小不变,但失败时重下载的文件是很小的,在linux环境执行以下命令,将文件分割成多个最大10兆的文件:

split -b 10m jdk-10_linux-x64_bin_ri.tar.gz jdk-10_linux-x64_bin_ri-
1
编写Dockerfile
Dockerfile内容如下,主要是安装必要的应用,另外关键的操作都有详细的注释,就不多说了:

#Docker image of source for OpenJDK
# VERSION 0.0.1
# Author: bolingcavalry

#基础镜像使用ubuntu:16.04
FROM ubuntu:16.04

#作者
MAINTAINER BolingCavalry <zq2599@gmail.com>

#定义boot jdk文件名
ENV BOOT_JDK_FILE_NAME jdk-10_linux-x64_bin_ri

#定义boot jdk安装目录
ENV BOOT_JDK_PATH /usr/lib/jvm

#定义boot jdk解压后的包名
ENV BOOT_JDK_PACKAGE_NAME jdk-10

#boot jdk的完全路径
ENV BOOT_JDK_HOME $BOOT_JDK_PATH/$BOOT_JDK_PACKAGE_NAME

#boot jdk相关的环境变量
ENV JAVA_HOME $BOOT_JDK_HOME
ENV JRE_HOME $BOOT_JDK_HOME/jre
ENV CLASSPATH .:$BOOT_JDK_HOME/lib:$JRE_HOME/lib
ENV PATH=$BOOT_JDK_HOME/bin:$PATH

#创建文件夹用于安装boot jdk
RUN mkdir $BOOT_JDK_PATH

#将分割好的boot jdk安装文件逐个复制到镜像中,分多步完成,这样下载过程中出现问题时,不至于全部重新开始下载
COPY ./$BOOT_JDK_FILE_NAME-ac $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ag $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ak $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ao $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-as $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ad $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ah $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-al $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ap $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-aa $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ae $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ai $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-am $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-aq $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ab $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-af $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-aj $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-an $BOOT_JDK_PATH/
COPY ./$BOOT_JDK_FILE_NAME-ar $BOOT_JDK_PATH/

#还原成完整的文件,再解压开,将boot JDK配置信息写入环境变量,创建jre目录,把lib放进去
RUN cat $BOOT_JDK_PATH/$BOOT_JDK_FILE_NAME-* > $BOOT_JDK_PATH/$BOOT_JDK_FILE_NAME.tar.gz \
&& tar -zxvf $BOOT_JDK_PATH/$BOOT_JDK_FILE_NAME.tar.gz -C $BOOT_JDK_PATH \
&& rm $BOOT_JDK_PATH/$BOOT_JDK_FILE_NAME.tar.gz \
&& rm $BOOT_JDK_PATH/$BOOT_JDK_FILE_NAME-* \
&& mkdir $BOOT_JDK_HOME/jre \
&& cp -r $BOOT_JDK_HOME/lib $BOOT_JDK_HOME/jre/

#备份旧的源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.backup

#复制新的源
COPY ./sources.list /etc/apt/

#apt更新
RUN apt-get update \
&& apt-get install -y file autoconf zip libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev libcups2-dev libfontconfig1-dev libasound2-dev

#命令行文件复制到工作目录
COPY ./cmd.sh /

#赋予可执行权限
RUN chmod a+x /cmd.sh

#启动执行
#CMD ["/bin/bash", "/cmd.sh"]
ENTRYPOINT ["/cmd.sh"]
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
看到这里您一定会有疑问:这么多行COPY命令,为什么不用BOOT_JDK_FILE_NAME-*,这样岂不是一行命令就够了?
您可以在镜像build成功后,用docker history命令看看文件的layer数量,用多个COPY命令逐个执行,每个命令都对应一个小的layer,这样用户下载镜像时就是在下载多个小文件了;

cmd.sh文件
cmd.sh的内容如下,可见当容器启动后,先完成configure,再执行make命令进行编译:

#!/bin/bash
#修改所属人和所属群组
echo "start chown and chgrp"
chown -R root /src/jdk11 && chgrp -R root /src/jdk11

cd /src/jdk11

#配置
echo "start configure"
bash /src/jdk11/configure

#开始编译,如果有入参,就作为make的参数
echo "start make"

if [ $# -gt 0 ]; then
   echo "make param is "$1
   make $1
else
   make
fi

echo "Compile successful!"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
source.list
这是构建镜像时,更新Ubuntu的时候用到的源,您可以自行从网上搜索,或者用我的git上的;

构建镜像
准备好上述材料后,整个文件夹应该是如下内容:

现在,在Dockerfile文件所在目录执行以下命令即可构建好镜像文件:

docker build -t bolingcavalry/buildopenjdk11:0.0.2 .
1
至此,镜像制作完毕,可以直接通过docker run命令来编译构建自己的OpenJDK了,相比在真实Linux环境编译,此方式更为简单方便;
--------------------- 
作者:博陵精骑 
来源:CSDN 
原文:

https://bcy.net/u/108606832643
https://bcy.net/u/107854206578
https://bcy.net/u/107853573461

12-10 03:46