Spring-boot: Recommend that DevTools is excluded when building something other than a fat jar such as a Docker image

Created on 4 Dec 2018  路  7Comments  路  Source: spring-projects/spring-boot

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)
...
documentation

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.

configurations {
  developmentOnly
  if (!isCiServer) {
    runtimeClasspath {
      extendsFrom developmentOnly
    }
  }
}

Seems to work, but seems to be "hacky"...

All 7 comments

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"...

Was this page helpful?
0 / 5 - 0 ratings