-1

I have built common mavne dependencies as a base docker image, but when I build a project Dockerfile, it still will download dependencies which will take a long time to build.

Mr.Cao
  • 1
  • 3

2 Answers2

1

Combine go-offline goal of maven-dependency-plugin, maven's offline mode with docker multistage builds.

A reference Dockerfile could be :

# Step : Test and package
FROM maven:3.5.3-jdk-8-alpine as builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline

COPY src/ /build/src/
# -o flag will instruct maven to build on offline mode
RUN mvn -o package

# Step : Package image
FROM openjdk:8-jre-alpine
EXPOSE 4567
CMD exec java $JAVA_OPTS -jar /app/my-app.jar
COPY --from=builder /build/target/*jar-with-dependencies.jar /app/my-app.jar

Invoking dependency:go-offline will fetch required artifacts on container's local repository. Thanks to docker layer caching, this step will be cached so it will be skipped in a new build attempt.

An important note is that copying pom.xml should precede source code copying as a change on pom.xml must trigger a new pull of maven artifacts as project's dependencies may have changed.

Reference

EDIT: Note that depending on your pom.xml, you may face an open Maven Dependency plugin issue on which some dependencies are not fetched from go-offline goal as they should, resulting in build failure. As a workaround, you can try Romain's answer.

leopal
  • 4,711
  • 1
  • 25
  • 35
  • First ,thanks for your answer. I have tried your suggestion,I just modified src, not pom.xml, but when command is running to "RUN mvn dependency:go-offline", build dependencies time is still too long everytime, dependencies cache was not used. Have you found out this issue ? – Mr.Cao Sep 06 '19 at 02:20
  • @Mr.Cao Sorry for the delay. I have updated my answer, main points of the update are the addition of `-o` flag on `mvn package` command and the info on edit section. – leopal Oct 11 '19 at 12:07
0

Using docker experimental features and buildit you can mount a (shared) cache volume during your builds for example:

# syntax = docker/dockerfile:experimental
FROM fabric8/maven-builder
...
RUN --mount=type=cache,target=/root/.m2 mvn versions:set -DnewVersion=1.1.43 && \
    mvn clean install ...
masseyb
  • 3,745
  • 1
  • 17
  • 29
  • thanks for your answer. In this way, Docker daemon needs to run in experimental mode. it's not suitable for developing. – Mr.Cao Sep 11 '19 at 02:00
  • It not being suitable is specific to your use case (e.g. suits us just fine). Can build a dind image with the daemon config baked in and use that as your portable development environment. – masseyb Sep 11 '19 at 05:54