英文:
Spring Boot DevTools being used inside docker container even after exclusion in gradle build
问题
我们正在使用Spring Boot来部署我们的应用程序。我们使用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 Boot项目中删除该依赖项的方法是正确的,但指定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
英文:
So we are using Spring boot to deliver our application. We use the Jib plugin to monitor create docker images and run them.
We use gradle to build the project and there dev tools is identified as a developmentOnly
dependency.
Just as mentioned in the spring docs at https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools .
However when it runs in the container in prod I still see it getting restarted now and then.
My question is does the gradle configuration not really exlude it from packaging.
Do i need to explicitly set the -Dspring.devtools.restart.enabled=false
parameter ?
Solution :
So turns out it was the gradle jib plugin playing games.
While the spring documentation is spot on about how to go about removing the dependency from gradle spring boot project. The technique of specifying a developmentOnly
only helps in telling gradle to ignore the dev tools. The jib gradle plugin has a mind of its own.
It includes all jars when building a docker image and there is no way to exclude any jar. The only reasonable way is to customize the gradle jib plugin in build.gradle to write this ,
jib {
from {
image 'gcr.io/distroless/java:11'
}
container {
jvmFlags = ['-Xms1G', '-Xmx1G', '-Dspring.devtools.restart.enabled = false']
}
}
This will make sure that even if the jar is included the container environment has the restart taken care of.
Reference : https://github.com/spring-projects/spring-boot/issues/15382
答案1
得分: 2
你可以通过在你的 application.properties
或者你特定的配置文件比如 application-cloud.properties
中设置 spring.devtools.restart.enabled=false
来实现这一点。如果这样做有效,请告诉我。
英文:
You can achieve that by setting spring.devtools.restart.enabled=false
in your application.properties
or your specific profile properties ex. application-cloud.properties
. Let me know if this works.
答案2
得分: 2
这里确实存在一些问题:
- Spring Boot有自己的自定义定义,而不是使用与配置文件相当的内容。他们的方法最适合Spring Boot用户,但由于所有这些自定义逻辑,集成起来相当困难。
- Jib无法了解每个框架的所有自定义实现。
我认为你应该这样做:
dependencies {
if (System.getProperty("development") == "true") {
// 包含Spring Boot开发工具依赖
}
}
当你想以开发模式运行或构建时,只需执行
./gradlew 任务名称 -Ddevelopment=true
英文:
There's really a few problems here:
- Springboot has its own custom definitions instead of using what would be the equivalent of profiles. Their approach is best for springboot users, but rather hard to integrate with given all their custom logic.
- Jib can't know all the custom implementation of each framework.
I really think what you should be doing is something like this:
dependencies {
if (System.getProperty("development") == true) {
// include the springboot devtool dependency
}
}
When you want to run or build in dev mode, just do
./gradlew whateverTask -Ddevelopment=true
答案3
得分: 2
以下是您要翻译的内容:
问题
最近我也遇到了相同的问题,看起来已经有一个非常直接的方法来解决它。
Jib 实际上将 spring-boot-devtools 视为运行时依赖项,并将其添加到镜像中。在我的情况下,对于仅在本地开发时使用的 h2 数据库 jar 也是如此。
此外,我不想在构建过程中处理任何额外的自定义参数,也不想通过配置关闭功能,如果我真的不希望在生产环境中使用它们。
解决方案
GoogleContainerTools 团队发布了一个 jib-extension 来直接处理 devtools 问题。有一个 Gradle 和 Maven 版本,它工作得非常完美。
然而,根据我的需求(也排除 h2),我决定使用 jib layer filter extension,这样我就可以使我的镜像尽可能接近 bootJar。
以下是在 Gradle 中的代码片段:
// 应位于 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'
}
}
}
}
}
}
英文:
Well, just faced the same problem recently and it seems there's already a very straight-forward way to solve it.
The problem
Jib is actually considering spring-boot-devtools as a runtime dependency and so, adding it to the image. In my case, this is also true for h2 database jar which is used only locally for development.
Also, I wouldn't like to deal with any extra custom parameter in my build, neither turn-off features by configuration if I don't really wanna them available at production.
Solution
GoogleContainerTools' team has released a jib-extension to deal with devtools problem directly. There's a Gradle and Maven version and it works flawlessly.
However, to my needs (also exclude h2) I've decided to use jib layer filter extension so I can keep my image as close to bootJar as possible.
Here goes the code snippet in 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'
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论