[Docker]構建maven鏡像並用鏡像打包

[Docker]構建maven鏡像並用鏡像打包

寫在前面

由於項目使用的maven版本較低,在DockerHub上沒有可以直接使用的maven鏡像,於是自己構建了maven鏡像,並使用該鏡像將項目工程打包。

爲什麼要構建maven鏡像呢?有了maven鏡像之後,就不需要再在新的開發環境中安裝maven了。鏡像中的maven版本固定,不會出現不同開發者使用不同版本maven打包出現不必要的問題。

構建過程和maven打包過程有一些需要注意的地方,記錄備查。

構建maven鏡像

前一篇博文中記錄了構建java8的過程。構建maven鏡像依賴於之前構建的java環境。簡而言之,就是先啓動一個java8的docker,然後在這個docker實例中安裝maven、配置環境變量、構建成鏡像,提交到私有registry。以後打包直接一句指令就可以啦。

docker實例中安裝maven

這一步跟在linux中安裝maven過程類似,簡略說一下。注意哦,以下是正常的安裝maven的步驟。但是在docker環境下會啓動maven有問題。先記下,後文講問題及我的解決方法。

  1. 假設你將需要安裝的maven壓縮包放在宿主機的~/software路徑,想把它影射成docker內部的/mnt/software
  2. 如果java8的基礎鏡像名字是java-base:1.8,則運行以下命令啓動一個以此docker實例:

    $ docker run -it -v ~/software:/mnt/software java-base:1.8 /bin/bash

    注意,對於java-base:1.8這個鏡像,docker會先搜索本地的images是否存在,如果不存在,默認會到dockerhub上下載。如果你之前是提交到dockerhub的,那還需要增加你的賬戶名(類似於zhangsan/java-base:1.8)。如果你是提交到自己搭建的私有registry,那麼需要在鏡像名前加上registry的名字(類似於myregistry.net:5000/java-base:1.8)。

  3. 此時已經attach到docker實例了。將maven壓縮包解壓、拷貝到需要安裝的路徑。/opt/tool/maven
  4. 如果有自定義的m2 settings.xml文件,則需要修改實例內部的~/.m2/目錄
  5. 設置profile文件:

    export M2_HOME=/opt/tool/maven
    export JAVA_HOME=/opt/tool/jdk1.8.0
    export JRE_HOME=${JAVA_HOME}/jre
    export CLASSPATH=.:$JAVA_HOME/lib:${JRE_HOME}/lib
    export PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin

    然後退出docker。運行docker ps -a找到剛纔退出的docker實例,container id是0d23cb11f494。然後把這個鏡像提交:

    $ docker commit 0d23cb11f494 mymaven:3.0

maven鏡像的問題

問題就是,這個看上去標準構建的鏡像,不能運行。
docker運行maven非常簡單:

docker run -it --rm --name maven-test -v `pwd`/project:/usr/src/mymaven mymaven:3.0 mvn package -DskipTests

其中/usr/src/mymaven是maven在容器中的運行路徑。
在運行時,總是報錯,無法找到$PATH,也就是找不到maven配置的環境變量。原來是剛纔我們在容器內配置的環境變量,在容器退出後就失效了。每次啓動容器時,docker都重新初始化了環境變量,所以配置的就沒用了。

解決方案

在剛纔創建好的maven鏡像的基礎上,通過Dockerfile的ENV指令增加對環境變量的配置,再生成一個鏡像。新鏡像中會有處理環境變量的layer,保證環境變量的有效性。

FROM mymaven:3.0
WORKDIR /usr/src/mymaven

ENV M2_HOME=/opt/tool/maven JAVA_HOME=/opt/tool/jdk1.8.0 JRE_HOME=/opt/tool/jdk1.8.0/jre \
            CLASSPATH=.:/opt/tool/jdk1.8.0/lib:/opt/tool/jdk1.8.0/lib
ENV PATH=${PATH}:${JAVA_HOME}/bin:${M2_HOME}/bin

COPY ./m2/settings.xml ${HOME}/.m2/settings.xml

然後構建鏡像:

$ docker build -t maven:3.0-jdk-8

再然後,打個tag,push到dockerhub或者你自己的registry。

稍作解釋:

  1. 多次嘗試後,寫成這樣子。必須將各種HOME的設置放在一個ENVlayer,然後在此基礎上,在增加一個設置PATHENVlayer才行。
  2. 將你的settings.xml文件放在宿主機,直接COPY到鏡像中。

用maven鏡像打jar包

打包的命令如下:

sudo docker run -it --rm -v <your-pom-dir>:/usr/src/mymaven maven:3.0-jdk-8 mvn package -DskipTest

鏡像名後的命令就是給容器的運行指令。這樣就可以在<your-pom-dir>/target中看到打好的包啦!

優化

由於容器是短暫的實體,每次退出後,之前下載的文件並不會保留,所以maven打包時下載的依賴包,每次都要重新下載。可以在啓動時,給容器的/root/.m2配置一個volume(依賴包默認下載在這個路徑)。這樣下次打包的時候,就會先看本地是否有,沒有再下載:

sudo docker run -it --rm -v <your-pom-dir>:/usr/src/mymaven -v <your-local-m2-volume>:/root/.m2 maven:3.0-jdk-8 mvn package -DskipTest

完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章