2017-02-13 96 views
6

我正在嘗試使用docker來自動化Maven構建。我想要構建的項目花費了將近20分鐘的時間來下載所有的依賴關係,因此我試圖構建一個可以緩存這些依賴關係的Docker鏡像,但似乎並沒有挽救它。我的Dockerfile是Maven碼頭緩存依賴關係

FROM maven:alpine 
RUN mkdir -p /usr/src/app 
WORKDIR /usr/src/app 
ADD pom.xml /usr/src/app 
RUN mvn dependency:go-offline 

圖像構建,它確實下載了所有內容。但是,生成的圖像與基本圖像maven:alpine的大小相同,所以它似乎沒有緩存圖像中的依賴關係。當我嘗試使用mvn compile的圖片時,它會在完成20分鐘的所有重新下載之後進行。

是否可以構建緩存我的依賴關係的Maven圖像,以便每次使用圖像執行構建時都不必下載它們?

我運行下面的命令:

docker build -t my-maven . 

docker run -it --rm --name my-maven-project -v "$PWD":/usr/src/mymaven -w /usr/src/mymaven my-maven mvn compile 

我的理解是,無論RUN在泊塢窗構建過程確實成爲導致圖像的一部分。

+0

製作一個數據容器,其中包含下載的工件...您建立了多少個模塊?你有多少次測試?導致20分鐘聽起來很長? – khmarbaise

+0

你能解釋一下數據容器的含義嗎?我想我最終會得到一個擁有這些數據的maven圖像。 「mvn dependency:go-offline」不會保存這些對本地文件系統的依賴關係嗎? –

+0

如果您對本地文件系統有任何更改,如果您重新啓動容器,那麼這些更改將被丟棄... – khmarbaise

回答

0

如果在容器已經啓動後下載依賴關係,那麼您需要在此容器上提交更改並使用下載的工件創建新圖像。

+0

我添加了一些說明,我只是構建Dockerfile。我沒有創建一個事實後需要承諾的容器。 –

0

我以前只有一個小問題。將在網絡上很多解決方案,但爲我工作時只需裝入一個容積爲行家modules目錄的一個:

mkdir /opt/myvolumes/m2 

然後在Dockerfile:

... 
VOLUME /opt/myvolumes/m2:/root/.m2 
... 

有更好的解決方案,但不是那麼簡單。

本博客文章更是不辭辛勞地幫助你緩存的一切:

https://keyholesoftware.com/2015/01/05/caching-for-maven-docker-builds/

+0

這確實有效,但這不是我想要完成的。我試圖構建一個封裝存儲庫/依賴關係的映像,以便我可以在任何地方運行映像,而無需首先爲具有依賴關係的容器卷準備裝載點。 –

+0

然後在Docker主機上構建項目一次(以填充〜/ .m2)並在構建圖像之前添加〜/ .m2目錄。換句話說,將〜/ .m2視爲源代碼的一部分。 – Bruno9779

+0

在碼頭構建階段,VOLUME不起作用。 – XPLOT1ON

3

事實證明我使用爲基礎的圖像具有定義

VOLUME "$USER_HOME_DIR/.m2" 
父圖像

請參閱:https://github.com/carlossg/docker-maven/blob/322d0dff5d0531ccaf47bf49338cb3e294fd66c8/jdk-8/Dockerfile

結果是,在構建過程中,所有文件都寫入$USER_HOME_DIR/.m2,但因爲它預計是一個卷,所以這些文件都不會與容器圖像一起保存。

目前在Docker中沒有任何方法來取消註冊該卷定義,所以有必要構建一個單獨的maven圖像,而不是使用官方的maven圖像。

+0

我想我遇到了同樣的問題。你有沒有找到一個好的解決方法? – FrustratedWithFormsDesigner

+1

我使用Docker卷並告訴maven爲我的Maven存儲庫緩存使用不同的路徑,例如'-Dmaven.repo.local =/mvn/.m2nrepo/repository' –

5

通常pom.xml文件沒有變化,但當您嘗試啓動docker映像構建時,其他src代碼會發生變化。在這種情況下,你可以這樣做:

FYI:

FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8 

MAINTAINER Eric Kim <[email protected]> 

ENV PITBULL_EUREKA=/usr/src/app 

RUN mkdir -p $PITBULL_EUREKA 

WORKDIR $PITBULL_EUREKA 

# add pom.xml only here, and download dependency 

ADD pom.xml $PITBULL_EUREKA 

RUN ["/usr/local/bin/mvn-entrypoint.sh", "mvn", "verify", "clean", "--fail-never"] 

# now we can add all source code and start compiling 

ADD . $PITBULL_EUREKA 

RUN ["mvn", "package"] 

EXPOSE 8888 

CMD ["java", "-jar", "./target/eureka-0.0.1-SNAPSHOT.jar"] 

所以關鍵是:

  1. 添加pom.xml文件。

  2. 然後mvn verify --fail-never它,它會下載maven依賴項。

  3. 然後添加所有源文件,然後開始編譯(mvn package)。

當有您的pom.xml更改或者是第一次運行該腳本,搬運工會做1 - > 2 - > 3。當有pom.xml文件進行更改,搬運工將跳過步驟1,2和直接做3。

這個簡單的技巧可以用在許多其他的包管理環境中。