<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ashim Regmi</title>
    <description>The latest articles on DEV Community by Ashim Regmi (@ashimregmi).</description>
    <link>https://dev.to/ashimregmi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1156594%2F90906064-fed5-40a1-9c8d-af117815b6e3.png</url>
      <title>DEV Community: Ashim Regmi</title>
      <link>https://dev.to/ashimregmi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashimregmi"/>
    <language>en</language>
    <item>
      <title>Make your builds faster using Docker's RUN cache</title>
      <dc:creator>Ashim Regmi</dc:creator>
      <pubDate>Fri, 08 Sep 2023 15:26:51 +0000</pubDate>
      <link>https://dev.to/ashimregmi/make-your-builds-faster-by-caching-m2-directory-using-dockers-run-cache-2l9g</link>
      <guid>https://dev.to/ashimregmi/make-your-builds-faster-by-caching-m2-directory-using-dockers-run-cache-2l9g</guid>
      <description>&lt;p&gt;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 &lt;a href="https://docs.docker.com/build/cache/#use-the-dedicated-run-cache"&gt;RUN cache&lt;/a&gt; has got you covered.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;First, let's begin by using a JDK as the base image for 1st stage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM eclipse-temurin:17-jdk-alpine AS build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, we mark a directory as our &lt;code&gt;WORKDIR&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WORKDIR /workspace/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we copy few files necessary to generate our .m2 repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, this is where we use RUN cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN \
    --mount=type=cache,target=/root/.m2 \
    ./mvnw dependency:resolve-plugins dependency:resolve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY src src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, We use the RUN cache to utilize the same local .m2 repository for the maven's &lt;code&gt;package&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN \
    --mount=type=cache,target=/root/.m2 \
    ./mvnw package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we extract the jar so that the next stage can use the extracted files to run the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN mkdir -p target/dependency &amp;amp;&amp;amp; (cd target/dependency; jar -xf ../*.jar)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the 2nd stage of the docker build to run the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voilà! Now you have an efficient Dockerfile that respects your valuable time.&lt;/p&gt;

&lt;p&gt;Here's a complete version of the Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 &amp;amp;&amp;amp; (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"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Signing off.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>docker</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
