If you're like me and dislike taking coffee breaks while your entire .m2 directory rebuilds from scratch, or if you're frustrated at the thought of waiting again for the build to complete after making a tiny modification to your pom.xml, don't worry because Docker's RUN cache has got you covered.
In this post, I'll demonstrate how to create a Dockerfile that leverages the RUN cache to efficiently cache a container's .m2 directory. It's worth noting that I'm using a Spring Boot project as an example.
First, let's begin by using a JDK as the base image for 1st stage.
FROM eclipse-temurin:17-jdk-alpine AS build
Second, we mark a directory as our WORKDIR
.
WORKDIR /workspace/app
Now, we copy few files necessary to generate our .m2 repository.
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
Next, this is where we use RUN cache.
RUN \
--mount=type=cache,target=/root/.m2 \
./mvnw dependency:resolve-plugins dependency:resolve
Now, copy all the source files. We've waited until this point to ensure that the previous steps are cached by Docker and won't need to be executed every time there's a change in the project's code.
COPY src src
Again, We use the RUN cache to utilize the same local .m2 repository for the maven's package
command.
RUN \
--mount=type=cache,target=/root/.m2 \
./mvnw package
Now, we extract the jar so that the next stage can use the extracted files to run the application.
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
Configure the 2nd stage of the docker build to run the application.
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.SpringApplication"]
Voilà! Now you have an efficient Dockerfile that respects your valuable time.
Here's a complete version of the Dockerfile.
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
RUN \
--mount=type=cache,target=/root/.m2 \
./mvnw dependency:resolve-plugins dependency:resolve
COPY src src
RUN \
--mount=type=cache,target=/root/.m2 \
./mvnw package
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.SpringApplication"]
Signing off.
Top comments (0)