From 95f9f67776dcf6617ff15307371d265c3dd0a9a6 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Mon, 3 Aug 2026 18:11:26 -0400 Subject: [PATCH] chore: Switch to ubuntu-resolute-builder as the default Buildpacks builder * replacing Noble * not addressing the spring-boot-cnb-test-builder still based on Noble yet; it could wait for this PR to be merged first. Signed-off-by: Anthony Dahanne --- .../modules/gradle-plugin/pages/packaging-oci-image.adoc | 8 ++++---- .../boot/gradle/tasks/bundling/BootBuildImageTests.java | 2 +- .../examples/aot-native-profile-buildpacks/pom.xml | 5 +++++ .../antora/modules/maven-plugin/pages/build-image.adoc | 4 ++-- .../java/org/springframework/boot/maven/ImageTests.java | 4 ++-- .../boot/buildpack/platform/build/BuildRequest.java | 4 +++- .../native-image/developing-your-first-application.adoc | 6 +++--- .../pages/packaging/native-image/advanced-topics.adoc | 3 ++- .../paketo/PaketoBuilderTests-plainDistZipJarApp.gradle | 2 +- .../image/paketo/PaketoBuilderTests-plainWarApp.gradle | 2 +- 10 files changed, 24 insertions(+), 16 deletions(-) diff --git a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc index 9ffcbe13a296..e445e16963bb 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc +++ b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc @@ -131,12 +131,12 @@ The following table summarizes the available properties and their default values | `builder` | `--builder` | Name of the builder image to use. -| `paketobuildpacks/builder-noble-java-tiny:latest` +| `paketobuildpacks/ubuntu-resolute-builder:latest` | `trustBuilder` | `--trustBuilder` | Whether to treat the builder as {url-buildpacks-docs}/for-platform-operators/how-to/integrate-ci/pack/concepts/trusted_builders/#what-is-a-trusted-builder[trusted]. -| `true` if the builder is one of `paketobuildpacks/builder-noble-java-tiny`, `paketobuildpacks/builder-jammy-java-tiny`, `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; `false` otherwise. +| `true` if the builder is one of `paketobuildpacks/ubuntu-resolute-builder`, `paketobuildpacks/ubuntu-resolute-builder-buildpackless`, `paketobuildpacks/builder-noble-java-tiny`, `paketobuildpacks/builder-jammy-java-tiny`, `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; `false` otherwise. | `imagePlatform` | `--imagePlatform` @@ -263,8 +263,8 @@ NOTE: The plugin detects the target Java compatibility of the project using the When using the default Paketo builder and buildpacks, the plugin instructs the buildpacks to install the same Java version. You can override this behavior as shown in the xref:packaging-oci-image.adoc#build-image.examples.builder-configuration[builder configuration] examples. -NOTE: The default builder `paketobuildpacks/builder-noble-java-tiny:latest` contains a reduced set of system libraries and does not include a shell. -Applications that require a shell to run a start script, as might be the case when the {url-gradle-docs-application-plugin}[`application` plugin] has been applied to generate a distribution zip archive, or that depend upon a system library that is not present, should override the `runImage` configuration to use one that includes a shell and a broader set of system libraries, such as `paketobuildpacks/ubuntu-noble-run:latest`. +NOTE: The default builder `paketobuildpacks/ubuntu-resolute-builder:latest` uses the `paketobuildpacks/ubuntu-resolute-run:latest` run image, which includes a shell and a broad set of system libraries. +Applications that want a reduced footprint and attack surface, as is typically the case for native images, should override the `runImage` configuration to use one that does not include a shell, such as `paketobuildpacks/ubuntu-resolute-run-tiny:latest`. diff --git a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java index ce72a74808e4..1bbb0b317291 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java +++ b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java @@ -194,7 +194,7 @@ void whenUsingDefaultConfigurationThenRequestHasPublishDisabled() { @Test void whenNoBuilderIsConfiguredThenRequestHasDefaultBuilder() { BuildRequest request = this.buildImage.createRequest(); - assertThat(request.getBuilder().getName()).isEqualTo("paketobuildpacks/builder-noble-java-tiny"); + assertThat(request.getBuilder().getName()).isEqualTo("paketobuildpacks/ubuntu-resolute-builder"); assertThat(request.isTrustBuilder()).isTrue(); } diff --git a/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/examples/aot-native-profile-buildpacks/pom.xml b/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/examples/aot-native-profile-buildpacks/pom.xml index 05682587d783..601746613c68 100644 --- a/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/examples/aot-native-profile-buildpacks/pom.xml +++ b/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/examples/aot-native-profile-buildpacks/pom.xml @@ -12,6 +12,11 @@ org.springframework.boot spring-boot-maven-plugin + + + paketobuildpacks/ubuntu-resolute-run-tiny + + build-image diff --git a/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/pages/build-image.adoc b/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/pages/build-image.adoc index 0c492ca6b557..c8299d043e57 100644 --- a/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/pages/build-image.adoc +++ b/build-plugin/spring-boot-maven-plugin/src/docs/antora/modules/maven-plugin/pages/build-image.adoc @@ -149,12 +149,12 @@ The following table summarizes the available parameters and their default values | `builder` + (`spring-boot.build-image.builder`) | Name of the builder image to use. -| `paketobuildpacks/builder-noble-java-tiny:latest` +| `paketobuildpacks/ubuntu-resolute-builder:latest` | `trustBuilder` + (`spring-boot.build-image.trustBuilder`) | Whether to treat the builder as {url-buildpacks-docs}/for-platform-operators/how-to/integrate-ci/pack/concepts/trusted_builders/#what-is-a-trusted-builder[trusted]. -| `true` if the builder is one of `paketobuildpacks/builder-noble-java-tiny`, `paketobuildpacks/builder-jammy-java-tiny`, `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; `false` otherwise. +| `true` if the builder is one of `paketobuildpacks/ubuntu-resolute-builder`, `paketobuildpacks/ubuntu-resolute-builder-buildpackless`, `paketobuildpacks/builder-noble-java-tiny`, `paketobuildpacks/builder-jammy-java-tiny`, `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; `false` otherwise. | `imagePlatform` + (`spring-boot.build-image.imagePlatform`) diff --git a/build-plugin/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ImageTests.java b/build-plugin/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ImageTests.java index 2e0c7b7a1802..60f2bc785858 100644 --- a/build-plugin/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ImageTests.java +++ b/build-plugin/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ImageTests.java @@ -73,7 +73,7 @@ void getBuildRequestWhenNameIsSetUsesName() { void getBuildRequestWhenNoCustomizationsUsesDefaults() { BuildRequest request = new Image().getBuildRequest(createArtifact(), mockApplicationContent()); assertThat(request.getName()).hasToString("docker.io/library/my-app:0.0.1-SNAPSHOT"); - assertThat(request.getBuilder().toString()).contains("paketobuildpacks/builder-noble-java-tiny"); + assertThat(request.getBuilder().toString()).contains("paketobuildpacks/ubuntu-resolute-builder"); assertThat(request.isTrustBuilder()).isTrue(); assertThat(request.getRunImage()).isNull(); assertThat(request.getEnv()).isEmpty(); @@ -111,7 +111,7 @@ void getBuildRequestWhenHasDefaultBuilderAndTrustBuilderUsesTrustBuilder() { Image image = new Image(); image.trustBuilder = false; BuildRequest request = image.getBuildRequest(createArtifact(), mockApplicationContent()); - assertThat(request.getBuilder().toString()).contains("paketobuildpacks/builder-noble-java-tiny"); + assertThat(request.getBuilder().toString()).contains("paketobuildpacks/ubuntu-resolute-builder"); assertThat(request.isTrustBuilder()).isFalse(); } diff --git a/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildRequest.java b/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildRequest.java index f3f996311da0..f249c6569531 100644 --- a/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildRequest.java +++ b/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildRequest.java @@ -48,11 +48,13 @@ */ public class BuildRequest { - static final String DEFAULT_BUILDER_IMAGE_NAME = "paketobuildpacks/builder-noble-java-tiny"; + static final String DEFAULT_BUILDER_IMAGE_NAME = "paketobuildpacks/ubuntu-resolute-builder"; static final String DEFAULT_BUILDER_IMAGE_REF = DEFAULT_BUILDER_IMAGE_NAME + ":latest"; static final List KNOWN_TRUSTED_BUILDERS = List.of( + ImageReference.of("paketobuildpacks/ubuntu-resolute-builder"), + ImageReference.of("paketobuildpacks/ubuntu-resolute-builder-buildpackless"), ImageReference.of("paketobuildpacks/builder-noble-java-tiny"), ImageReference.of("paketobuildpacks/builder-jammy-java-tiny"), ImageReference.of("paketobuildpacks/builder-jammy-tiny"), diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/native-image/developing-your-first-application.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/native-image/developing-your-first-application.adoc index 8c6d409a3db0..ce7dbeb31ca6 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/native-image/developing-your-first-application.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/native-image/developing-your-first-application.adoc @@ -33,9 +33,9 @@ This means you can just type a single command and quickly get a sensible image i The resulting image doesn't contain a JVM, instead the native image is compiled statically. This leads to smaller images. -NOTE: The CNB builder used for the images is `paketobuildpacks/builder-noble-java-tiny:latest`. -It has a small footprint and reduced attack surface. It does not include a shell and contains a reduced set of system libraries. -If you need more tools in the resulting image, you can use `paketobuildpacks/ubuntu-noble-run:latest` as the *run* image. +NOTE: The CNB builder used for the images is `paketobuildpacks/ubuntu-resolute-builder:latest`. +For native images, configure the `runImage` to use `paketobuildpacks/ubuntu-resolute-run-tiny:latest`, which has a small footprint and reduced attack surface: it does not include a shell and contains a reduced set of system libraries. +If you need more tools in the resulting image, you can use the default `paketobuildpacks/ubuntu-resolute-run:latest` as the *run* image. NOTE: You have to build your application with at least JDK 25, because Buildpacks use the same GraalVM native-image version as the Java version used for compilation. diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/packaging/native-image/advanced-topics.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/packaging/native-image/advanced-topics.adoc index ff92a6052929..ec8248d827f4 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/packaging/native-image/advanced-topics.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/packaging/native-image/advanced-topics.adoc @@ -67,7 +67,8 @@ Assuming an AOT processed Spring Boot executable jar built as `myproject-0.0.1-S [source,shell] ---- -$ pack build --builder paketobuildpacks/builder-noble-java-tiny \ +$ pack build --builder paketobuildpacks/ubuntu-resolute-builder \ + --run-image paketobuildpacks/ubuntu-resolute-run-tiny \ --path target/myproject-0.0.1-SNAPSHOT.jar \ --env 'BP_NATIVE_IMAGE=true' \ my-application:0.0.1-SNAPSHOT diff --git a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainDistZipJarApp.gradle b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainDistZipJarApp.gradle index d591c9f803f6..c8de82e972cf 100644 --- a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainDistZipJarApp.gradle +++ b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainDistZipJarApp.gradle @@ -55,6 +55,6 @@ application { bootBuildImage { archiveFile = distZip.archiveFile - runImage = "paketobuildpacks/ubuntu-noble-run:latest" + runImage = "paketobuildpacks/ubuntu-resolute-run:latest" environment = ['BP_JVM_VERSION': java.targetCompatibility.getMajorVersion()] } diff --git a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle index c47e47d828ab..324991d76677 100644 --- a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle +++ b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle @@ -47,7 +47,7 @@ war { bootBuildImage { archiveFile = war.archiveFile - runImage = "paketobuildpacks/ubuntu-noble-run:latest" + runImage = "paketobuildpacks/ubuntu-resolute-run:latest" environment = [ 'BP_JVM_VERSION': java.targetCompatibility.getMajorVersion(), 'BP_TOMCAT_VERSION': '11.*',