PAw*_*l_Z 13 java caching gradle docker gradlew
我正在做大学项目,我们需要一次运行多个 Spring Boot 应用程序。
我已经使用 gradle docker 镜像配置了多阶段构建,然后在 openjdk:jre 镜像中运行应用程序。
这是我的 Dockerfile:
FROM gradle:5.3.0-jdk11-slim as builder
USER root
WORKDIR /usr/src/java-code
COPY . /usr/src/java-code/
RUN gradle bootJar
FROM openjdk:11-jre-slim
EXPOSE 8080
WORKDIR /usr/src/java-app
COPY --from=builder /usr/src/java-code/build/libs/*.jar ./app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
Run Code Online (Sandbox Code Playgroud)
我正在使用 docker-compose 构建和运行所有内容。docker-compose 的一部分:
website_server:
build: website-server
image: website-server:latest
container_name: "website-server"
ports:
- "81:8080"
Run Code Online (Sandbox Code Playgroud)
当然,第一次构建需要很长时间。Docker 正在拉取它的所有依赖项。我对此没有意见。
目前一切正常,但代码中的每一个小变化都会导致一个应用程序的构建时间大约为 1 分钟。
构建日志的一部分: docker-compose up --build
Step 1/10 : FROM gradle:5.3.0-jdk11-slim as builder
---> 668e92a5b906
Step 2/10 : USER root
---> Using cache
---> dac9a962d8b6
Step 3/10 : WORKDIR /usr/src/java-code
---> Using cache
---> e3f4528347f1
Step 4/10 : COPY . /usr/src/java-code/
---> Using cache
---> 52b136a280a2
Step 5/10 : RUN gradle bootJar
---> Running in 88a5ac812ac8
Welcome to Gradle 5.3!
Here are the highlights of this release:
- Feature variants AKA "optional dependencies"
- Type-safe accessors in Kotlin precompiled script plugins
- Gradle Module Metadata 1.0
For more details see https://docs.gradle.org/5.3/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :compileJava
> Task :processResources
> Task :classes
> Task :bootJar
BUILD SUCCESSFUL in 48s
3 actionable tasks: 3 executed
Removing intermediate container 88a5ac812ac8
---> 4f9beba838ed
Step 6/10 : FROM openjdk:11-jre-slim
---> 0e452dba629c
Step 7/10 : EXPOSE 8080
---> Using cache
---> d5519e55d690
Step 8/10 : WORKDIR /usr/src/java-app
---> Using cache
---> 196f1321db2c
Step 9/10 : COPY --from=builder /usr/src/java-code/build/libs/*.jar ./app.jar
---> d101eefa2487
Step 10/10 : ENTRYPOINT ["java", "-jar", "app.jar"]
---> Running in ad02f0497c8f
Removing intermediate container ad02f0497c8f
---> 0c63eeef8c8e
Successfully built 0c63eeef8c8e
Successfully tagged website-server:latest
Run Code Online (Sandbox Code Playgroud)
每次它冻结后 Starting a Gradle Daemon (subsequent builds will be faster)
我正在考虑使用缓存的 gradle 依赖项添加卷,但我不知道这是否是问题的核心。我也找不到很好的例子。
有没有办法加快构建速度?
Evg*_*yst 25
构建需要很多时间,因为每次构建 Docker 镜像时 Gradle 都会下载所有插件和依赖项。
无法在映像构建时安装卷。但是可以引入新的阶段,将下载所有依赖项并将缓存为 Docker 镜像层。
FROM gradle:5.6.4-jdk11 as cache
RUN mkdir -p /home/gradle/cache_home
ENV GRADLE_USER_HOME /home/gradle/cache_home
COPY build.gradle /home/gradle/java-code/
WORKDIR /home/gradle/java-code
RUN gradle clean build -i --stacktrace
FROM gradle:5.6.4-jdk11 as builder
COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle
COPY . /usr/src/java-code/
WORKDIR /usr/src/java-code
RUN gradle bootJar -i --stacktrace
FROM openjdk:11-jre-slim
EXPOSE 8080
USER root
WORKDIR /usr/src/java-app
COPY --from=builder /usr/src/java-code/build/libs/*.jar ./app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
Run Code Online (Sandbox Code Playgroud)
Gradle 插件和依赖缓存位于$GRADLE_USER_HOME/caches. GRADLE_USER_HOME必须设置为不同于/home/gradle/.gradle. /home/gradle/.gradle在父 Gradle Docker 镜像中定义为卷并在每个镜像层之后被擦除。
在示例代码GRADLE_USER_HOME中设置为/home/gradle/cache_home.
在builder舞台摇篮缓存复制,以避免重新下载的依赖关系:COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle。
cache只有在build.gradle更改时才会重建舞台。当 Java 类发生更改时,会重用所有依赖项的缓存图像层。
这种修改可以减少构建时间,但是使用 Java 应用程序构建 Docker 镜像的更干净的方法是Google 的Jib。有一个Jib Gradle 插件,它允许为 Java 应用程序构建容器镜像,而无需手动创建 Dockerfile。使用应用程序构建映像并运行容器类似于:
gradle clean build jib
docker-compose up
Run Code Online (Sandbox Code Playgroud)
Docker 将其图像缓存在“层”中。您运行的每个命令都是一个层。在给定层中检测到的每个更改都会使其后面的层失效。如果缓存失效,那么失效的层必须从头开始构建,包括依赖项。
我建议分开你的构建步骤。有一个前一层,仅将依赖项规范复制到映像中,然后运行一个命令,该命令将导致 Gradle 下载依赖项。完成后,将源代码复制到刚刚执行此操作的同一位置,然后运行真正的构建。
这样,只有当gradle文件发生变化时,前面的层才会失效。
我还没有使用 Java/Gradle 完成此操作,但在这篇博文的指导下,我在 Rust 项目中遵循了相同的模式。
Vet*_*ras -2
我对 docker 内部了解不多,但我认为问题是每个新docker build命令都会复制所有文件并构建它们(如果它检测到至少一个文件中的更改)。那么这很可能会改变几个罐子,并且第二步也需要运行。
我的建议是在终端(docker 外部)上构建,并且仅 docker 构建应用程序映像。
这甚至可以通过 gradle 插件自动化:
| 归档时间: |
|
| 查看次数: |
10158 次 |
| 最近记录: |