Search code examples
javaspringspring-bootjib

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


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


Solution

  • There's really a few problems here:

    1. 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.
    2. 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