I want to cache Maven dependencies in a layer of the build stage of my Docker Multi Stage Build.
My Dockerfile looks as follows:
FROM maven:3-jdk-8 as mvnbuild
RUN mkdir -p /opt/workspace
WORKDIR /opt/workspace
COPY pom.xml .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package
FROM openjdk:8-jre-alpine
...
```
I based this Dockerfile on the example provided in the Docker Multi Stage Build blog post (also available on Github).
When I run the build, instead of seeing the dependencies downloaded once by dependency:resolve
and then re-used by package
, I am seeing the dependencies downloaded by both steps.
Has anyone got this working? What am I doing wrong here?
I came across the same question. I found out it's due to differences between Maven targets (e.g. dependency:resolve
vs dependency:resolve-plugin
). Basically, dependency:resolve
is for application libraries, dependency:resolve-plugin
is for plugin libraries. Hence, libraries are downloaded in both RUN steps.
dependency:resolve tells Maven to resolve all dependencies and displays the version. JAVA 9 NOTE: will display the module name when running with Java 9.
dependency:resolve-plugins tells Maven to resolve plugins and their dependencies.
https://maven.apache.org/plugins/maven-dependency-plugin/index.html
Even with dependency:resolve-plugins
, Maven will not download all required libraries as package
is a built-in target and requires additional libraries which dependency:resolve-plugin
won't know to resolve in the first RUN. I also tried dependency:go-offline
without success.
One solution is to run your build targets before and after adding your code to the build image. This will pull all the plugin dependencies into the lower layer allowing them to be re-used.
Applying this solution to your example above is as follows:
FROM maven:3-jdk-8 as mvnbuild
RUN mkdir -p /opt/workspace
WORKDIR /opt/workspace
COPY pom.xml .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml dependency:resolve-plugins dependency:resolve clean package
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml clean package
FROM openjdk:8-jre-alpine