Docker cache gradle dependencies

后端 未结 4 1179
攒了一身酷
攒了一身酷 2020-12-12 22:41

I\'m trying to deploy our java web application to aws elastic beanstalk using docker, the idea is to be able to run the container locally for development and testing and eve

4条回答
  •  醉梦人生
    2020-12-12 22:57

    I faced this issue. As you might agree, it is a best practice to download dependencies alone as a separate step while building the docker image. It becomes little tricky with gradle, since there is no direct support for downloading just dependencies.

    Option 1 : Using docker-gradle Docker image


    We can use pre-built gradle docker image to build the application. This ensures that it's not a local system build but a build done on a clean docker image.

    docker volume create --name gradle-cache
    docker run --rm -v gradle-cache:/home/gradle/.gradle -v "$PWD":/home/gradle/project -w /home/gradle/project gradle:4.7.0-jdk8-alpine gradle build
    ls -ltrh ./build/libs
    
    • gradle cache is loaded here as a volume. So subsequent builds will reuse the downloaded dependencies.
    • After this, we could have a Dockerfile to take this artifact and generate application specific image to run the application.
    • This way, the builder image is not required. Application build flow and Application run flow is separated out.
    • Since the gradle-cache volume is mounted, we could reuse the downloaded dependencies across different gradle projects.

    Option 2 : Multi-stage build


    ----- Dockerfile -----

    FROM openjdk:8 AS TEMP_BUILD_IMAGE
    ENV APP_HOME=/usr/app/
    WORKDIR $APP_HOME
    COPY build.gradle settings.gradle gradlew $APP_HOME
    COPY gradle $APP_HOME/gradle
    RUN ./gradlew build || return 0 
    COPY . .
    RUN ./gradlew build
    
    FROM openjdk:8
    ENV ARTIFACT_NAME=your-application.jar
    ENV APP_HOME=/usr/app/
    WORKDIR $APP_HOME
    COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
    EXPOSE 8080
    CMD ["java","-jar",$ARTIFACT_NAME]
    

    In the above Dockerfile

    • First we try to copy the project's gradle files alone, like build.gradle, gradlew etc.,
    • Then we copy the gradle directory itself
    • And then we try to run the build. At this point, there is no other source code files exists in the directory. So build will fail. But before that it will download the dependencies. 
    • Since we expect the build to fail, I have tried a simple technique to return 0 and allow the docker to continue execution
    • this will speed up the subsequent build flows, since all the dependencies are downloaded and docker cached this layer. Comparatively, Volume mounting the gradle cache directory is still the best approach.
    • The above example also showcases multi-stage docker image building, which avoid multiple docker build files.

提交回复
热议问题