Maven是目前最流行的Java項目管理工具之一,提供了強大的包依賴管理和應用建構功能。
Docker提供了官方的Maven鏡像可以用于管理和建構Java應用。與直接安裝使用Maven工具相比,使用Docker鏡像具有更好的可移植性,可以友善地進行版本切換,非常适合在持續內建過程中使用。
關于Maven官方鏡像的用法可以參考使用文檔
使用阿裡雲加速
Maven官方倉庫在國内網絡下的下載下傳速度實在是讓人欲哭無淚,利用阿裡雲的Maven鏡像可以大大提升軟體包下載下傳速度。
它的配置檔案settings.xml如下
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
/usr/share/maven/ref/repository
aliyun-nexus
*
http://maven.aliyun.com/nexus/content/groups/public/
aliyun-nexus-public-snapshots
public-snapshots
http://maven.aliyun.com/nexus/content/repositories/snapshots/
阿裡雲容器服務提供了預建構的Docker鏡像可供直接使用registry.cn-hangzhou.aliyuncs.com/acs/maven,
我們可以像使用mvn指令一樣,直接在目前目錄中執行如下指令來建構應用
docker run -it --rm --name maven -v "$(pwd)":/usr/src/app -w /usr/src/app registry.cn-hangzhou.aliyuncs.com/acs/maven mvn clean install
如果希望能夠緩存下載下傳的maven倉庫,我們可以利用Docker的檔案卷來實作
首先執行如下指令建立一個名為“maven-repo”的檔案卷
docker volumecreate --name maven-repo
在之後的調用中,将其挂載到maven鏡像中倉庫下載下傳目錄上
docker run -it --rm --name maven -v "$(pwd)":/usr/src/app -v maven-repo:/usr/share/maven/ref -w /usr/src/app registry.cn-hangzhou.aliyuncs.com/acs/maven mvn clean install
這樣maven倉庫就不會每次都下載下傳一遍了。
優化Dockerfile提升建構速度
我們可以在Dockerfile中建構應用,并利用Docker建構時的分層緩存機制來提升建構速度
下面是一個示例Dockerfile.build檔案
FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8
ENV MY_HOME=/usr/src/app
RUNmkdir -p $MY_HOME
WORKDIR$MY_HOME
ADDpom.xml $MY_HOME
# get all the downloads out of the way
RUN["/usr/local/bin/mvn-entrypoint.sh","mvn","verify","clean","--fail-never"]
# add source
ADD. $MY_HOME
# run maven verify
RUN["/usr/local/bin/mvn-entrypoint.sh","mvn","verify"]
其中的一個重要技巧就是先把pom.xml添加到工作目錄,利用maven指令下載下傳應用所需jar包之後,再添加應用源檔案進行編譯。這樣隻要pom.xml沒有更新就不會重新下載下傳所依賴的jar包,可以大大加快鏡像建構速度。
我們可以通過如下指令來編譯應用
docker build -t builder-img -f Dockerfile.build .
應用編譯與Docker鏡像建構分離
對于靜态編譯型語言,我們通常需要将應用編譯過程與鏡像建構過程分離。主要有以下兩個考慮:
最終生成的Docker鏡像不應該包含源代碼
最終生成的Docker鏡像應該最小化,不應該包含編譯時工具
我們可以将應用編譯結果從Docker鏡像中拷貝出來,方法如下
docker build -t builder-img -f Dockerfile.build .
docker create --name builder builder-img
docker cp builder:/usr/src/app/target ./target
這時maven建構的結果就被拷貝到目前目錄的“target”子目錄下面了。
之後,我們可以利用另外一個Dockerfile來建構應用鏡像了。篇幅有限不再贅述。
總結
本文以Maven為例介紹了Docker在應用建構中的一些常見技巧
利用國内的鏡像站點加速軟體包下載下傳:阿裡雲和阿裡集團提供了大量開源項目的包管理鏡像站點,阿裡雲容器服務開源項目 https://github.com/AliyunContainerService 中提供很多帶加速能力的Ruby/Python/Node/Maven基礎鏡像可供參考。
在Docker鏡像建構過程中,為了防止由于代碼變化反複下載下傳軟體包,可以先把應用配置檔案加入Dockerfile,在編譯之前提前下載下傳軟體包。比如Ruby的Gemfile, Python的requirements.txt,和NodeJs的package.json都可以采用類似方法。這樣可以更好地利用Docker的分層緩存機制加速鏡像建構過程。
應用編譯應該與Docker鏡像建構分離