在离线构build中cachingMaven父项

TL / DR:如何cachingpom.xml文件的<parent>以便我的构build可以在离线模式下运行?

我正在使用Docker来构build一个Maven项目。 我的目标是向构build添加两个步骤:一个下载所有的依赖关系,另一个构build项目。 以下是我的Dockerfile到目前为止的样子:

 FROM maven:3.3-jdk-8 # Download the project dependencies (so they can be cached by Docker) ADD pom.xml /runtime/ WORKDIR /runtime RUN mvn dependency:go-offline RUN mvn dependency:resolve-plugins # Mount the local repository ADD . /runtime # Build the service RUN mvn clean package -o -DskipTests 

这似乎为插件工作正常。 我检查了/root/.m2/repository ,一切似乎都是按顺序的。

编辑:当双重检查/root/.m2/repository目录,它不再存在。 出于某种原因,Maven并没有将任何依赖保存到这个位置。

编辑2:在构buildDocker镜像之后,没有/root/.m2/repository目录。 但是,如果我在Docker容器内的shell中运行mvn dependency:go-offline ,则创build目录时不会出现问题。

当我尝试构build我的应用程序时,出现以下错误:

 [ERROR] [ERROR] Some problems were encountered while processing the POMs: [FATAL] Non-resolvable parent POM for com.example:service:1.2: Cannot access central (http://jcenter.bintray.com) in offline mode and the artifact org.springframework.boot:spring-boot-starter-parent:pom:1.4.0.M3 has not been downloaded from it before. and 'parent.relativePath' points at wrong local POM @ line 14, column 13 @ [ERROR] The build could not read 1 project -> [Help 1] [ERROR] [ERROR] The project com.sample:service:1.2 (/runtime/pom.xml) has 1 error [ERROR] Non-resolvable parent POM for com.oe:graph-service:1.2: Cannot access central (http://jcenter.bintray.com) in offline mode and the artifact org.springframework.boot:spring-boot-starter-parent:pom:1.4.0.M3 has not been downloaded from it before. and 'parent.relativePath' points at wrong local POM @ line 14, column 13 -> [Help 2] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException 

问题似乎是mvn dependency:go-offline不解决父。 当我在离线模式下运行构build时,它会中断。

以下是我的pom.xml文件的相关部分:

 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> ... <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.M3</version> </parent> ... <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>bintray</name> <url>http://jcenter.bintray.com</url> </repository> <repository> <id>repository.springsource.snapshot</id> <name>SpringSource Snapshot Repository</name> <url>http://repo.springsource.org/snapshot</url> </repository> <repository> <id>spring-milestones</id> <url>http://repo.spring.io/milestone</url> </repository> </repositories> <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.scala</groupId> <artifactId>spring-scala_2.11</artifactId> <version>1.0.0.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- disabling Spring cloud AWS until proper testing harnesses can be set up --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>LATEST</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-aws-autoconfigure</artifactId> <version>1.1.0.RELEASE</version> </dependency> ... </dependencies> ... </project> 

如果你自定义maven的settings.xml文件,你可以保存你的存储库文件的图像。

创buildsettings.xml的自定义版本,修改localRepository设置,如下所示:

 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository --> <localRepository>/usr/share/maven/repo</localRepository> ... 

然后在构build图像时覆盖默认configuration:

 FROM maven:3-jdk-8 COPY settings.xml /usr/share/maven/conf/settings.xml RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ADD . /usr/src/app RUN mvn dependency:go-offline RUN mvn clean package 

现在你的仓库存储在/usr/share/maven/repo

使用onbuild

你也可以使用ONBUILD创build一个基本的图像,这将允许为每个maven项目定制configuration的图像。

喜欢这个:

 FROM maven:3-jdk-8 COPY settings.xml /usr/share/maven/conf/settings.xml RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ONBUILD ADD . /usr/src/app ONBUILD RUN mvn dependency:go-offline ONBUILD RUN mvn clean package 

然后build立图像:

 docker build -t mvn_bldr . 

这将为其他Maven图像创build一个模板 。 然后你可以创build你的自定义下游图像:

 FROM mvn_bldr 

如果要进一步自定义图像,可以添加更多指令,模板的每个指令都将在FROM mvn_bldr命令之后触发,如文档中所示:

触发器将在下游构build的上下文中执行,就像它已经在下游Dockerfile中的FROM指令之后立即插入一样。

看起来像在Docker中使用RUN就好像在shell脚本中执行命令一样,但事实并非如此。 RUN每个实例都会应用到由上一个命令创build的更改所产生的新容器。 所以每个命令都在一个新的容器上下文中执行。

Dockerifles可以包含一个VOLUME引用,它在Docker容器中挂载一个外部目录。 如果卷内有任何文件,这些文件将被清除。 如果你没有明确指定一个卷,Docker很乐意创build一个空文件夹。

虽然我的Dockerfile不包含对VOLUME的明确引用,但是它的父代却是。 所以,即使我的mvn dependency:go-offline命令正在运行,这些文件在下一步被Dockerfile docker-maven Dockerfile指定的VOLUME Dockerfile

最后,我找不到一个让maven Docker镜像工作的好方法,所以我切换到了openjdk镜像,并通过apt-get来安装maven