--By performing gradlew build
with only Gradle related files COPY
, create a cache layer for downloading dependent files.
--The build time of Docker image has been reduced by about 70% (* There are differences depending on the environment and project.)
It took more than 5 minutes to build the Docker image for the Spring Boot application. Therefore, it takes time to build and deploy to the inspection environment. There was a problem that it took time for trial and error, which can only be done in the inspection environment.
Sample Dockerfile
FROM openjdk:11.0.8-jre-slim as builder
WORKDIR /app
# build.Add only files that depend on gradle,
#Idle gradle build to cache dependent files
COPY *.gradle gradle.* gradlew /app/
COPY gradle/ /app/gradle/
RUN ./gradlew build -x test --parallel --continue > /dev/null 2>&1 || true
#Incorporate and build code changes after the following lines
COPY . /app
RUN ./gradlew build -x test --parallel
FROM openjdk:11.0.8-jre-slim
COPY --from=builder /app/build/libs/app.jar /app/app.jar
CMD ["java", "-jar", "/app/app.jar"]
Tips: We use multi-stage builds to separate the build container and the execution container.
I think that the Dockerfile that does a common Gradle build is as follows.
FROM openjdk:11.0.8-jre-slim as builder
WORKDIR /app
COPY . /app
RUN ./gradlew build -x test --parallel
The problem with this Dockerfile is that it takes a long time to build because the gradle binaries and dependent files are downloaded every time you build. This time, we will speed up by caching the download of this gradle binary and dependent files in the image layer.
Unfortunately, there are no Gradle commands that only download binaries and dependent files. However, the download is done at the beginning of the build runtime. Therefore, even if the build fails, the build is idled to perform pre-download.
$ ./gradlew build --continue > /dev/null 2>&1 || true
By adding the --continue
option, even a build with multiple projects can be executed to the end and the dependent files can be downloaded.
COPY
commandThe COPY
command checks whether the cache can be used based on the checksum of the file.
(* It is not the last update date or access date and time)
Therefore, you can create a layer that downloads dependent files by COPY
the minimum required files for gradle build and idle build.
Since build.gradle
etc. are rarely changed, the cache can be used at many builds, and the build time can be reduced.
COPY *.gradle gradle.* gradlew /app/
COPY gradle/ /app/gradle/
By using the above Gradle-dependent file cache, you can reduce the image build time of Docker. Regarding the reduction effect, it depends on the environment and Java project, but I will share my application result.
Before application: 4min 56sec
After application: 1min 42sec
By applying this method, we were able to reduce the build time by about 70%.
We hope that the above method will reduce the image build time of Docker using Gradle in the world as much as possible. If you find any mistakes in the description, please let us know in the comments.
Recommended Posts