This isn't really an issue with Jib per se, or rather it is potentially an issue with any container that is built without the jar file (so the same applies to containers built by a buildpack for cloud foundry for instance). Jib is an easy way to re-create the problem.
E.g. in Petclinic:
$ mvn com.google.cloud.tools:jib-maven-plugin:0.9.13:dockerBuild -Dimage=petclinic
$ docker run petclinic
...
2018-12-04 14:29:22.282 INFO 1 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
...
This looks like a packaging or dependency scope issue. If DevTools is on the classpath, it will always be active to some degree (the restarter is disabled in tests). To fix this, DevTools should be excluded from the image that Jib builds in the same way that it is excluded from the fat jars that Boot's Maven and Gradle plugins build. The behaviour of Jib's Maven plugin doesn't feel like something that's in Boot's control to me. Perhaps you can configure Jib not to include the dependency, either by changing DevTools dependency's scope in your pom or by configuring Jib's Maven plugin to exclude it?
Jib doesn't let you exclude dependencies, but it probably should (I found this issue but they don't seem to want to fix it). The best I came up with is switching off the restarter:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>0.10.1</version>
<configuration>
<container>
<jvmFlags>
<jvmFlag>-Dspring.devtools.restart.enabled=false</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
I agree that it's not a Spring Boot problem per se, but it is a problem that our users will encounter, so it's probably a good idea to at least document the issue and any workarounds we find.
We could add something here.
The way I do this is with maven profiles. A profile that includes devtools, and active by default. And a docker profile that defines jib parameters. Locally I have devtools, and a jenkins build uses -Pdocker to disable devtools and build images to my registry.
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>docker</id>
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<!-- omitted for brevity -->
</plugin>
</plugins>
</build>
</profile>
</profiles>
So for gradle we should use to prevent
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
But how to prevent https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin to include devtools while creating the docker image?
@kguelzau That's really a question for the maintainers of Jib's Gradle plugin.
I don't think they are willing to change that (see https://github.com/GoogleContainerTools/jib/issues/1254).
I just tested a solution to prevent the extendsFrom when the build happens on the ci server.
"isCiServer" is true depending on some env keys.
configurations {
developmentOnly
if (!isCiServer) {
runtimeClasspath {
extendsFrom developmentOnly
}
}
}
Seems to work, but seems to be "hacky"...
Most helpful comment
I don't think they are willing to change that (see https://github.com/GoogleContainerTools/jib/issues/1254).
I just tested a solution to prevent the extendsFrom when the build happens on the ci server.
"isCiServer" is true depending on some env keys.
Seems to work, but seems to be "hacky"...