1. 程式人生 > >製作Docker映象,用來下載OpenJDK11原始碼

製作Docker映象,用來下載OpenJDK11原始碼

《極簡,利用Docker僅兩行命令就能下載和編譯OpenJDK11》一文中,我們用以下命令實現了OpenJDK11原始碼的下載:

docker run \
--rm \
-it \
-v /usr/local/work/openjdksrc:/output \
bolingcavalry/openjdksrc11:0.0.2

今天我們就來看下Docker映象bolingcavalry/openjdksrc11:0.0.2的製作過程,看看它做了哪些事情來簡化下載過程;

環境資訊

  1. 作業系統:Ubuntu 16.04.5 LTS;
  2. Docker:18.06.1-ce;

準備材料

本次映象用到了以下材料:

  1. Dockerfile:製作Docker映象的指令碼檔案;
  2. cmd.sh:容器啟動後執行的命令指令碼;
  3. OpenJDK11原始碼壓縮包(參考《Ubuntu環境下載OpenJDK11原始碼》);

您可以選擇直接從GitHub下載上述所有內容,地址和連結資訊如下表所示:

名稱 連結 備註
專案主頁 https://github.com/zq2599/openjdksrc11 該專案在GitHub上的主頁
git倉庫地址(https) https://github.com/zq2599/openjdksrc11.git 該專案原始碼的倉庫地址,https協議
git倉庫地址(ssh) [email protected]:zq2599/openjdksrc11.git 該專案原始碼的倉庫地址,ssh協議

要注意的問題

製作映象前有兩個問題先考慮好:

  1. 基礎映象儘量小,由於容器啟動後要執行一些shell命令,所以選用僅含bash工具的bash:5.0-rc;
  2. OpenJDK11原始碼包不小(超過1G),因此做成的映象也很大,使用者下載映象時,一旦網路問題下載失敗,docker會自動重試,此時是重新下載,這意味著之前的下載都白做了,為了緩解這個問題,可以把整個原始碼壓縮包分割成多個小檔案,這樣雖然整體大小不變,但是失敗時重新下載的檔案是很小的,在linux環境執行以下命令,將整個OpenJDK11原始碼壓縮包分割成多個最大10兆的檔案:
split -b 10m jdk11.tar.gz jdk11-

編寫Dockerfile

Dockerfile內容如下,可見大部分內容是複製檔案的操作,其餘部分已有詳細的註釋,就不多說了:

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

#基礎映象使用bash:5.0-rc,特點是體積小
FROM bash:5.0-rc

#作者
MAINTAINER BolingCavalry <[email protected]>

#定義原始碼存放目錄
ENV SRC_PATH /src

#定義OpenJDK原始碼資料夾名稱
ENV OPENJDK_SRC_PACKAGE_NAME jdk11

#建立目錄
RUN mkdir $SRC_PATH

#把分割過的原始碼複製到工作目錄,這麼寫可以保證每個檔案layer都不大,這樣下載映象時如果中途失敗,就不用重新下載一個巨大的layer
COPY ./$OPENJDK_SRC_PACKAGE_NAME-af $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-an $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-av $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bd $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bl $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bt $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cb $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cj $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cr $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cz $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dh $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dp $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dx $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ef $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ag $SRC_PATH/ 
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ao $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-aw $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-be $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bm $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bu $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cc $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ck $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cs $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-da $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-di $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dq $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dy $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-eg $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ah $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ap $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ax $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bf $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bn $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bv $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cd $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cl $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ct $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-db $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dj $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dr $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dz $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-eh $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-aa $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ai $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-aq $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ay $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bg $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bo $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bw $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ce $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cm $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cu $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dc $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dk $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ds $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ea $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ei $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ab $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-aj $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ar $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-az $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bh $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bp $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bx $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cf $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cn $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cv $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dd $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dl $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dt $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-eb $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ej $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ac $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ak $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-as $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ba $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bi $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bq $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-by $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cg $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-co $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cw $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-de $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dm $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-du $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ec $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ek $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ad $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-al $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-at $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bb $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bj $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-br $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bz $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ch $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cp $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cx $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-df $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dn $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dv $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ed $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-el $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ae $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-am $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-au $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bc $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bk $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-bs $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ca $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ci $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cq $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-cy $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dg $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-do $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-dw $SRC_PATH/
COPY ./$OPENJDK_SRC_PACKAGE_NAME-ee $SRC_PATH/

#命令列檔案複製到工作目錄
COPY ./cmd.sh /

RUN chmod a+x /cmd.sh

CMD ["bash", "/cmd.sh"]

看到這裡您一定會有疑問:這麼多行COPY命令,為什麼不用OPENJDK_SRC_PACKAGE_NAME-*,這樣豈不是一行命令就夠了?
您可以在映象build成功後,用docker history命令看看檔案的layer數量,用多個COPY命令逐個執行,每個命令都對應一個小的layer,這樣使用者下載映象時就是在下載多個小檔案了;

cmd.sh檔案

cmd.sh的內容如下,可見當容器啟動後,先將分割後的多個小檔案通過cat命令恢復成完整的jdk11.tar.gz檔案,再解壓,然後刪除jdk11.tar.gz檔案:

echo "start build gz file"
cat $SRC_PATH/$OPENJDK_SRC_PACKAGE_NAME-* > /output/$OPENJDK_SRC_PACKAGE_NAME.tar.gz
echo "gz file build success, start unzip"
tar -zxvf /output/$OPENJDK_SRC_PACKAGE_NAME.tar.gz -C /output
echo "unzip success, start remove gz file"
rm /output/$OPENJDK_SRC_PACKAGE_NAME.tar.gz
echo "download openjdk11 source successful!"

構建映象

在Dockerfile檔案所在目錄執行以下命令即可構建好映象檔案:

docker build -t bolingcavalry/openjdksrc11:0.0.2 .

至此,映象製作完畢,可以通過Docker來下載完整的OepnJDK11原始碼了,如果電腦空間緊張,docker run命令執行完畢後,記得用docker rmi bolingcavalry/openjdksrc11:0.0.2刪除映象;