I'm building a Spring Boot 3.1.0 application and deploying it by means of Cloud Native Buildpacks from a Gradle Kotlin DSL build script. To tune some image properties, I'm setting the following in my build.gradle.kts
script:
tasks.named<BootBuildImage>("bootBuildImage") {
verboseLogging.set(true)
// ...
environment.set(mapOf(
"BPL_JMX_ENABLED" to "true",
"BPL_DEBUG_ENABLED" to "true",
"BPL_JAVA_NMT_ENABLED" to "false",
"BPL_SPRING_CLOUD_BINDINGS_DISABLED" to "true"
))
}
I even see in the build log that these properties are recognized during build stage:
...
[creator] Launch Configuration:
[creator] $BPL_DEBUG_ENABLED true enables Java remote debugging support
[creator] $BPL_DEBUG_PORT 8000 configure the remote debugging port
...
[creator] Launch Configuration:
[creator] $BPL_SPRING_CLOUD_BINDINGS_DISABLED true whether to auto-configure Spring Boot environment properties from bindings
...
However, when the app is starting as a Docker container, none of the properties are picked up by the launcher. Here is an excerpt from the container's stdout with manual line breaks for clarity:
Spring Cloud Bindings Enabled
2023-05-20T07:48:25.857843881Z Picked up JAVA_TOOL_OPTIONS:
-Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties
-XX:+ExitOnOutOfMemoryError
-XX:ActiveProcessorCount=1
-XX:MaxDirectMemorySize=10M
-Xmx31494K
-XX:MaxMetaspaceSize=97109K
-XX:ReservedCodeCacheSize=240M
-Xss1M
-XX:+UnlockDiagnosticVMOptions
-XX:NativeMemoryTracking=summary
-XX:+PrintNMTStatistics
-Dorg.springframework.cloud.bindings.boot.enable=true
2023-05-20T07:48:28.285693854Z
I expect here to see "Spring Cloud Bindings Disabled" and a JVM option like -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000
. Accordingly, none of the desired ports opened.
No errors or warnings were observed neither in the build log nor in the run log.
How can I understand what went wrong and how to fix it?
There are two types of environment variable configuration properties that Paketo buildpacks understand: build time and launch time (also called run time).
BP_
.BPL_
.You can set build time properties as environment variables passed to pack (pack build -e ..
) or to Spring Boot build tools as you're doing here.
To set launch time configuration, you need to set those environment variables using your container runtime of choice. That could be Docker or Kubernetes or CloudFoundry or whatever.
In this case, you're using docker run
, so you'd add -e BPL_JMX_ENABLED=true -e BPL_DEBUG_ENABLED=true -e BPL_JAVA_NMT_ENABLED=true -e BPL_SPRING_CLOUD_BINDINGS_DISABLED=true
.
The reason there is a difference is so that you can toggle these settings on/off without rebuilding your container.
If you would like to have these settings baked into the container image so they are automatic, you can do that. The process is defined here.
In short, you'd modify your configuration like this:
environment.set(mapOf(
"BPE_DEFAULT_BPL_JMX_ENABLED" to "true",
"BPE_DEFAULT_BPL_DEBUG_ENABLED" to "true",
"BPE_DEFAULT_BPL_JAVA_NMT_ENABLED" to "false",
"BPE_DEFAULT_BPL_SPRING_CLOUD_BINDINGS_DISABLED" to "true"
))
Then when you build, these environment variables will be activated automatically. You won't need to include them with your runtime configuration.
The downside as I mentioned above is that you'll need to rebuild the image when you want to change them.