I’m trying to figure out how to create a two-stage Docker build using Maven
that would properly utilise Docker layer caching. Containing the whole
build in a Docker container without external dependencies on volume mounts
(for .m2 cache) has a lot of advantages.
The only missing piece of the puzzle I can’t figure out is how to force
Maven to download ALL dependencies just by using the pom file and not
executing any compilation. The idea behind is to:
1. copy the pom file into the image
2. use maven to download all dependencies
3. copy the sources to the image
4. use maven to build the final artifact
This way Docker will reuse the layer containing the dependencies if the pom
file didn’t change. So dependency caching would be implemented in a
Docker-ish way that works anywhere the Docker daemon is present as opposed
to relying on Maven being installed and artifacts getting stored in a
shared .m2/repository directory.
Now the problem - Maven’s lazy downloading of dependencies. Even if I try
to execute “mvn dependency:go-offline” Maven still doesn’t download plugins
and other dependencies, which would only be required during the packaging
phase. So the following Docker file doesn’t work as intended:
FROM maven AS build
ADD pom.xml /build
RUN mvn dependency:go-offline
ADD src /build/src
RUN mvn -o package
COPY --from=build /build/target/app.jar /app
CMD java -jar /app/app.jar
Maven will still start downloading more dependencies on line 6.
I found a workaround for this - execute “mvn package” with a single fake
main class on line 4, but this is not a nice solution. Can anyone give me
some option I’m missing or confirm that this is the way things are? In that
case I can go ahead write a blog post showing my workaround to help other
struggling with the same problem. Thank you!