2017-02-13 104 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。

这个简单的技巧可以用在许多其他的包管理环境中。