Spring Boot DevTools 在 docker 容器内使用,即使在 gradle build 中排除之后

Spring Boot DevTools being used inside docker container even after exclusion in gradle build

所以我们正在使用 Spring 引导来交付我们的应用程序。我们使用 Jib 插件来监控创建 docker 图像和 运行 它们。 我们使用 gradle 构建项目,开发工具被识别为 developmentOnly 依赖项。 正如 spring 文档中所述 https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools .

然而,当它 运行 在生产容器中时,我仍然看到它不时重新启动。 我的问题是 gradle 配置并没有真正将其排除在打包之外。 我需要明确设置 -Dspring.devtools.restart.enabled=false 参数吗?

解决方案:

原来是gradle jib插件在玩游戏。 虽然 spring 文档是关于如何从 gradle spring 引导项目中删除依赖项的。指定 developmentOnly 的技术仅有助于告诉 gradle 忽略开发工具。 jib gradle 插件有自己的想法。

它在构建 docker 图像时包括所有 jar,并且无法排除任何 jar。唯一合理的办法是在build.gradle中自定义gradle jib插件来写这个,

 jib {
    from {
        image 'gcr.io/distroless/java:11'
    }
    container {
        jvmFlags = ['-Xms1G', '-Xmx1G', '-Dspring.devtools.restart.enabled = false']
    }
}

这将确保即使包含 jar,容器环境也会重新启动。

参考:https://github.com/spring-projects/spring-boot/issues/15382

您可以通过在 application.properties 或您的特定配置文件属性中设置 spring.devtools.restart.enabled=false 来实现。 application-cloud.properties。让我知道这是否有效。

这里确实有几个问题:

  1. Springboot 有自己的自定义定义,而不是使用相当于配置文件的定义。他们的方法最适合 springboot 用户,但很难与他们所有的自定义逻辑集成。
  2. Jib无法知道每个框架的所有自定义实现。

我真的认为你应该做的是这样的:

dependencies {
  if (System.getProperty("development") == true) {
    // include the springboot devtool dependency
  }
}

当您想 运行 或在开发模式下构建时,只需执行

./gradlew whateverTask -Ddevelopment=true

好吧,最近刚遇到同样的问题,似乎已经有一个非常直接的方法可以解决它。

问题

Jib 实际上将 spring-boot-devtools 视为运行时依赖项,因此将其添加到映像中。就我而言,这对于仅在本地用于开发的 h2 数据库 jar 也是如此。 此外,我不想在我的构建中处理任何额外的自定义参数,如果我真的不想在生产中使用它们,也不会通过配置关闭它们。

解决方案

GoogleContainerTools 的团队发布了一个 jib-extension 来直接处理 devtools 问题。有一个 Gradle and Maven 版本,它运行完美。

但是,根据我的需要(也排除 h2),我决定使用 jib 层过滤器扩展 这样我就可以使图像尽可能接近 bootJar。

这里是 gradle 中的代码片段:

// should be at the top of build.gradle
buildscript {
    dependencies {
        classpath('com.google.cloud.tools:jib-layer-filter-extension-gradle:0.1.0')
    }
}
jib {
    // ...
    pluginExtensions {
        pluginExtension {
            implementation = 'com.google.cloud.tools.jib.gradle.extension.layerfilter.JibLayerFilterExtension'
            configuration {
                filters {
                    filter {
                        glob = '**/h2-*.jar'
                    }
                    filter {
                        glob = '**/spring-boot-devtools-*.jar'
                    }
                }
            }
        }
    }
}

在此处检查此扩展程序的 Gradle and Maven 版本。