gradle 连续构建技巧在 docker 容器中不起作用

Posted

技术标签:

【中文标题】gradle 连续构建技巧在 docker 容器中不起作用【英文标题】:gradle continuous build trick doesn't work in docker container 【发布时间】:2020-11-05 19:04:58 【问题描述】:

您好,我正在尝试使用here 中描述的技巧来允许在 docker 容器内连续构建。当我在主机上打开两个单独的终端时,这个技巧可以正常工作,但在 docker 容器中使用时会失败。

docker-compose.yml

  build_server:
    image: gradle:6.3.0-jdk8
    working_dir: /home/gradle/server
    volumes:
      - ./server:/home/gradle/server
    command: ["gradle", "build", "--continuous", "-x", "test"]

  server:
    image: gradle:6.3.0-jdk8
    working_dir: /home/gradle/server
    volumes:
      - ./server:/home/gradle/server
    ports:
      - 8080:8080
    depends_on:
      - build_server
    restart: on-failure
    command: ["gradle", "bootRun"]

我从服务器容器得到的错误信息:

server_1         | FAILURE: Build failed with an exception.
server_1         |
server_1         | * What went wrong:
server_1         | Gradle could not start your build.
server_1         | > Could not create service of type ScriptPluginFactory using BuildScopeServices.createScriptPluginFactory().
server_1         |    > Could not create service of type ChecksumService using BuildSessionScopeServices.createChecksumService().
server_1         |       > Timeout waiting to lock checksums cache (/home/gradle/server/.gradle/checksums). It is currently in use by another Gradle instance.
server_1         |         Owner PID: unknown
server_1         |         Our PID: 31
server_1         |         Owner Operation: unknown
server_1         |         Our operation:
server_1         |         Lock file: /home/gradle/server/.gradle/checksums/checksums.lock

看起来 gradle 已经在本地缓存文件上添加了锁,并阻止 bootRun 任务在另一个容器中运行。但是,当我在主机上的两个终端中运行任务时,或者当我只运行 build_server 容器并在主机终端上运行 bootRun 时,这个技巧可以正常工作。我想知道为什么它在 docker 容器中不起作用。感谢您提前提供帮助!

【问题讨论】:

如果您挂载相同的 gradle 主文件夹或项目文件夹(锁定文件所在的位置),我很确定每个容器中的守护进程都需要能够相互通信。但我不知道使用了哪些端口以及如何使其工作,如果可能的话...... @BjørnVester 感谢您的信息。在那种情况下,也许我应该在一个容器中运行这两个任务? 是的,这可能会奏效。 【参考方案1】:

通过为服务器容器设置不同的项目缓存目录找到了解决方法。即用以下命令替换命令

command: ["gradle", "bootRun", "--project-cache-dir=/tmp/cache"]

可能不是最好的解决方案,但它确实规避了由 gradle 的锁引起的问题。

【讨论】:

这对我帮助很大,我在使用共享挂载的 Vagrant 和 IntelliJ 时遇到了同样的问题,这救了我!

以上是关于gradle 连续构建技巧在 docker 容器中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

项目构建--Gradle--Docker打包(五)

如何为 Java 应用程序构建 docker 容器

三个技巧,将Docker镜像体积减小90%

将参数传递给build.gradle

将参数传递给 build.gradle

Docker 中缓慢的 gradle 构建。缓存 gradle 构建