Hello,
i have the normal vanilla Spring Boot 3.0.0-RC1 with only org.graalvm.buildtools.native as extra plugin. You can download it from here Spring Initializr
When i try to build with gradlew bootBuildImage with buildpacks and environment it gives me an error.
Running creator
[creator] Restoring data for SBOM from previous image
[creator] ===> DETECTING
[creator] ERROR: No buildpack groups passed detection.
[creator] ERROR: Please check that you are running against the correct path.
[creator] ERROR: failed to detect: no buildpacks participating
My bootBuildImage task is configured in build.gradle:
tasks.named('bootBuildImage') {
builder = 'docker.io/paketobuildpacks/builder:tiny'
runImage = 'docker.io/paketobuildpacks/run:tiny-cnb'
buildpacks = ['gcr.io/paketo-buildpacks/bellsoft-liberica:9.9.0-ea', 'gcr.io/paketo-buildpacks/java-native-image']
environment = [
'BP_NATIVE_IMAGE_BUILD_ARGUMENTS': '--verbose'
]
}
The --verbose is only a test, i try to add a reflection-config.json to native image.
When i remove the environment part from task configuration everything is fine.
plugins {
id 'org.springframework.boot' version '3.0.0-RC1'
id 'io.spring.dependency-management' version '1.1.0'
id 'org.graalvm.buildtools.native' version '0.9.16'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('bootBuildImage') {
builder = 'docker.io/paketobuildpacks/builder:tiny'
runImage = 'docker.io/paketobuildpacks/run:tiny-cnb'
buildpacks = ['gcr.io/paketo-buildpacks/bellsoft-liberica:9.9.0-ea', 'gcr.io/paketo-buildpacks/java-native-image']
environment = [
'BP_NATIVE_IMAGE_BUILD_ARGUMENTS': '--verbose'
]
}
tasks.named('test') {
useJUnitPlatform()
}
Did i anything wrong? Can i not use environment and buildpacks in combination?
Thank you.
Comment From: scottfrederick
@bitbaggi This should work if you also add 'BP_NATIVE_IMAGE': 'true' to the environment in your build configuration. The Spring Boot Gradle plugin adds that by default, but it appears your configuration is overriding all environment variables set by default.
Comment From: wilkinsona
I don't think this is a bug. The syntax used is assigning a new Map to the environment rather than adding an entry to it. You can add an entry like this:
tasks.named('bootBuildImage') {
environment['BP_NATIVE_IMAGE_BUILD_ARGUMENTS'] = '--verbose'
}
Or add multiple entries like this:
environment.putAll([
'BP_NATIVE_IMAGE_BUILD_ARGUMENTS': '--verbose',
'EXAMPLE': 'VALUE'
])
I think it's important that we support assignment replacing our defaults so that users can take complete control of the environment if needs be.
Comment From: scottfrederick
We should review the documentation for bootBuildImage and use the additive form for lists and maps in our examples then, to prevent this type of problem (and so everyone doesn't have to figure out the Groovy or Kotlin syntax).
Comment From: bitbaggi
Yeah, thank you @wilkinsona
environment['BP_NATIVE_IMAGE_BUILD_ARGUMENTS'] = '--verbose' is working
Comment From: wilkinsona
Thanks for the confirmation, @bitbaggi. I'm going to re-open this issue so that we can review the documentation.
Comment From: candrews
I've submitted an MR to update the documentation as discussed in this issue: https://github.com/spring-projects/spring-boot/pull/33424
Comment From: philwebb
Closing in favor of PR #33424. Thanks @candrews!
Comment From: gregjotau
@philwebb I might be missing something, but I think it was extremely difficult to find documentation for how to customize the container images created by bootBuildImage.
FROM amazoncorretto:23
COPY build/libs/learning-app-0.0.1.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "/app.jar"]
I have a Dockerfile that I deploy with a tool that relies upon curl being available (for healthcheck) in the container image.
But I cannot find out which builder / image / other config I need to set to make the image be "just as if I used the Dockerfile above, but with layering and other optimizations buildpacks does for me"
// creates smaller docker images, buildpacks
tasks.named<org.springframework.boot.gradle.tasks.bundling.BootBuildImage>("bootBuildImage") {
imageName.set("U/A:latest")
publish.set(true)
docker {
publishRegistry {
username = "U"
password = System.getenv("DOCKER_REGISTRY_TOKEN")
}
}
environment.set(
mapOf(
"BP_IMAGE_LABELS" to "service=\"A\"",
"BP_JVM_VERSION" to "23"
)
)
}
Not sure if it is me just missing the fundamentals, or if there is a lack of documentation on this :)
Comment From: wilkinsona
If you're not sure that you have a grasp of the fundamentals, I would recommend reading https://paketo.io if you haven't already done so.
The paketo.io documentation generally talks about configuring things using the pack CLI, for which bootBuildImage is an alternative. It's generally a matter of reading Paketo documentation to learn how to configure something using the pack CLI and then reading the Boot documentation to learn the equivalent bootBuildImage settings.
Within the Paketo documentation you'll find details of how to use an alternative JVM in the image. It looks like you want to use Amazon Corretto which is provided by paketo-buildpacks/amazon-corretto. You can learn how to configure the buildpacks that are used when building an image with bootBuildImage in the documentation for Boot's Gradle plugin.
If you have any further questions, please follow up on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Comment From: gregjotau
If you're not sure that you have a grasp of the fundamentals, I would recommend reading https://paketo.io if you haven't already done so.
The paketo.io documentation generally talks about configuring things using the
packCLI, for whichbootBuildImageis an alternative. It's generally a matter of reading Paketo documentation to learn how to configure something using thepackCLIand then reading the Boot documentation to learn the equivalentbootBuildImage` settings.Within the Paketo documentation you'll find details of how to use an alternative JVM in the image. It looks like you want to use Amazon Corretto which is provided by
paketo-buildpacks/amazon-corretto. You can learn how to configure the buildpacks that are used when building an image withbootBuildImagein the documentation for Boot's Gradle plugin.If you have any further questions, please follow up on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Hi,
OK regarding issues, made a stackoverflow: https://stackoverflow.com/questions/79082552/how-to-include-curl-in-image-built-with-bootbuildimage-spring-boot-that-uses-p
An in addition I solved it by upgrading to the new version of kamal, kamal 2, which does not rely on curl being available in the container.
With regards to distribution, that was not the issue at hand, it was more about "how to include other stuff you might need" in the image, like curl. Because Paketo by default, seems to only create super-optimized images, and I would assume that this is the case also for amazoncorretto.