spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.4k stars 40.74k forks source link

Unable to start image built using bootBuildImage #41458

Closed GeorgeJose7 closed 4 months ago

GeorgeJose7 commented 4 months ago

I am trying to build an Image for my Springboot App the Springboot version iam an using is 3.3.1 with Java 21 and gradle. The Docker version : 27.0.3 OS : macOS 14.5 (M2 Apple silicon)

The container image starts with out any problem when I use the following pack command to build the image:

pack build my-spring-app --path . --builder paketobuildpacks/builder-jammy-base \
--buildpack gcr.io/paketo-buildpacks/amazon-corretto:latest \
--buildpack gcr.io/paketo-buildpacks/java:latest \
--buildpack gcr.io/paketo-buildpacks/spring-boot \
--env BP_JVM_VERSION=21

The container also starts without errors when I do not customize the buildpacks in build.gradle file.

Error Scenario

I am using the following build.gradle file to configure the plugin.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.1'
    id 'io.spring.dependency-management' version '1.1.4'
    id("org.springdoc.openapi-gradle-plugin") version "1.8.0"
}

group = 'my-group'
version = 0.0.1

java {
    sourceCompatibility = '21'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    mavenLocal()
    maven {
        url 'my-codeartefactrepo'
        credentials {
            username "aws"
            password System.env.CODEARTIFACT_AUTH_TOKEN
        }
    }
}

ext {
    set('springCloudVersion', "2023.0.0")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'org.postgresql:postgresql'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    developmentOnly 'org.springframework.boot:spring-boot-devtools'

    implementation 'org.springframework.cloud:spring-cloud-starter-config'

    //o auth
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    //api doc
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'

    implementation platform('software.amazon.awssdk:bom:2.20.56')
    implementation 'software.amazon.awssdk:s3'

    implementation 'org.springframework.boot:spring-boot-starter-cache'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'

}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

bootBuildImage {
    verboseLogging = true
    builder = "paketobuildpacks/builder-jammy-base"
    buildpacks = [
            "gcr.io/paketo-buildpacks/amazon-corretto:latest",
                  "gcr.io/paketo-buildpacks/java:latest",
                  "gcr.io/paketo-buildpacks/spring-boot"
    ]
    environment = ["BP_JVM_VERSION": "21"]
    imageName = "${project.name}:${project.version}"
}

I am receiving the error while starting the container Image built with ./gradlew bootBuildImage

Error Message

$ docker run -p 8080:8080 my-spring-app:0.2.0
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Calculating JVM memory based on 7456912K available memory
For more information on this calculation, see https://paketo.io/docs/reference/java-reference/#memory-calculator
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx6774883K -XX:MaxMetaspaceSize=170028K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 7456912K, Thread Count: 250, Loaded Class Count: 27605, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
ERROR: failed to launch: direct exec: no such file or directory

How can I resolve this this issue and start up the docker container when using bootBuildImage ?

wilkinsona commented 4 months ago

I can't reproduce the behavior that you have described. Running ./gradlew bootBuildImage for a project with the same bootBootBuildImage configuration as you have shown above succeeds and the container starts. While I am using an Intel Mac, I would not expect that to make a difference such that the container fails to launch as it's doing for you.

The output of pack inspect for the container image that does not start may help to identify the problem. In my case, it is the following:

pack inspect docker.io/library/gh-41458:0.0.1-SNAPSHOT 
Inspecting image: docker.io/library/gh-41458:0.0.1-SNAPSHOT

REMOTE:
(not present)

LOCAL:

Stack: io.buildpacks.stacks.jammy

Base Image:
  Reference: fd60bad31aa19e5d9a22abe6c6ed36f98b331e114640c82a612c5f781af0e48f
  Top Layer: sha256:a1a9b58b291ff97a8edd1d3b111051912de613613f04148183aeb2e7ddcb5ba7

Run Images:
  index.docker.io/paketobuildpacks/run-jammy-base:latest

Rebasable: true

Buildpacks:
  ID                                         VERSION        HOMEPAGE
  paketo-buildpacks/amazon-corretto          8.5.1          https://github.com/paketo-buildpacks/amazon-corretto
  paketo-buildpacks/ca-certificates          3.8.2          https://github.com/paketo-buildpacks/ca-certificates
  paketo-buildpacks/bellsoft-liberica        10.8.1         https://github.com/paketo-buildpacks/bellsoft-liberica
  paketo-buildpacks/syft                     1.47.1         https://github.com/paketo-buildpacks/syft
  paketo-buildpacks/executable-jar           6.10.1         https://github.com/paketo-buildpacks/executable-jar
  paketo-buildpacks/dist-zip                 5.8.1          https://github.com/paketo-buildpacks/dist-zip
  paketo-buildpacks/spring-boot              5.30.1         https://github.com/paketo-buildpacks/spring-boot

Processes:
  TYPE                  SHELL        COMMAND        ARGS                                                      WORK DIR
  web (default)                      java           org.springframework.boot.loader.launch.JarLauncher        /workspace
  executable-jar                     java           org.springframework.boot.loader.launch.JarLauncher        /workspace
  task                               java           org.springframework.boot.loader.launch.JarLauncher        /workspace
GeorgeJose7 commented 4 months ago

The output of the pack inspect docker.io/library/file-object-manager:0.2.0 for me similar

 pack inspect docker.io/library/file-object-manager:0.2.0
Inspecting image: docker.io/library/file-object-manager:0.2.0

REMOTE:
(not present)

LOCAL:

Stack: io.buildpacks.stacks.jammy

Base Image:
  Reference: fd60bad31aa19e5d9a22abe6c6ed36f98b331e114640c82a612c5f781af0e48f
  Top Layer: sha256:a1a9b58b291ff97a8edd1d3b111051912de613613f04148183aeb2e7ddcb5ba7

Run Images:
  index.docker.io/paketobuildpacks/run-jammy-base:latest

Rebasable: true

Buildpacks:
  ID                                         VERSION        HOMEPAGE
  paketo-buildpacks/amazon-corretto          8.5.1          https://github.com/paketo-buildpacks/amazon-corretto
  paketo-buildpacks/ca-certificates          3.8.2          https://github.com/paketo-buildpacks/ca-certificates
  paketo-buildpacks/bellsoft-liberica        10.8.1         https://github.com/paketo-buildpacks/bellsoft-liberica
  paketo-buildpacks/syft                     1.47.1         https://github.com/paketo-buildpacks/syft
  paketo-buildpacks/executable-jar           6.10.1         https://github.com/paketo-buildpacks/executable-jar
  paketo-buildpacks/dist-zip                 5.8.1          https://github.com/paketo-buildpacks/dist-zip
  paketo-buildpacks/spring-boot              5.30.1         https://github.com/paketo-buildpacks/spring-boot

Processes:
  TYPE                  SHELL        COMMAND        ARGS                                                      WORK DIR
  web (default)                      java           org.springframework.boot.loader.launch.JarLauncher        /workspace
  executable-jar                     java           org.springframework.boot.loader.launch.JarLauncher        /workspace
  task                               java           org.springframework.boot.loader.launch.JarLauncher        /workspace

I am still getting the same error.

docker run -p 8080:8080 docker.io/library/file-object-manager:0.2.0
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Calculating JVM memory based on 7416488K available memory
For more information on this calculation, see https://paketo.io/docs/reference/java-reference/#memory-calculator
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx6734459K -XX:MaxMetaspaceSize=170028K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 7416488K, Thread Count: 250, Loaded Class Count: 27605, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
ERROR: failed to launch: direct exec: no such file or directory

The only line that caught my I was the following in the error

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

When I remove the Amazon Corretto Buildpack the container startup properly.

bootBuildImage {
    verboseLogging = true
    builder = "paketobuildpacks/builder-jammy-base"
    buildpacks = [
            //"gcr.io/paketo-buildpacks/amazon-corretto:latest",
            "gcr.io/paketo-buildpacks/java:latest",
            "gcr.io/paketo-buildpacks/spring-boot"
    ]
    environment = [
            "BP_JVM_VERSION": "21"
    ]

    imageName = "${project.name}:${project.version}"
}
wilkinsona commented 4 months ago

Maybe it is an ARM-related problem.

What happens if you use pack but point it to an already-built jar file? Something like this:

$ pack build my-spring-app --path build/libs/gh-41458-0.0.1-SNAPSHOT.jar --builder paketobuildpacks/builder-jammy-base \
--buildpack gcr.io/paketo-buildpacks/amazon-corretto:latest \
--buildpack gcr.io/paketo-buildpacks/java:latest \
--buildpack gcr.io/paketo-buildpacks/spring-boot \
--env BP_JVM_VERSION=21

This changes how the image is built and more closely aligns with what bootBuildImage will do.

GeorgeJose7 commented 4 months ago

I was able to build the image and run it with with the pack build and pointing it to the jar file.

I was also able to build the image and run it by changing the builder image. With paketobuildpacks/builder-jammy-tinythe image is built successfully and I was able to run the docker container.

I guess the problem is with the builder image.

scottfrederick commented 4 months ago

Paketo buiders and buildpacks to not fully support ARM architectures. Mac M1 and M2 machines may try to emulate AMD, leading to unpredictable results when building and running images that are built for AMD.

For now, you can try changing the builder to paketobuildpacks/builder-jammy-buildpackless-tiny, which does have ARM support. This will require you to list all buildpacks explicitly, which you appear to be doing that already.

You can follow the progress of ARM support in Paketo by joining the Paketo Slack and subscribing to the #arm channel.

ChildrenGreens commented 4 months ago

@scottfrederick I have the same problem, when can I solve it?

scottfrederick commented 4 months ago

@ChildrenGreens I described a work-around in my comment above. If you're asking when the Paketo project will have ARM-based images that work more reliably on Mac M1/M2 machines, that's a question the Paketo team will have to answer. The best way to keep up-to-date with that is to join the Paketo Slack and subscribe to the #arm channel.

ChildrenGreens commented 4 months ago

@scottfrederick

I resolved the issue of running it on my M2 Apple silicon machine in the following way, which made me very happy and grateful. However, there is a more troublesome problem. When I upload my Docker image to an x64 architecture server and run it there, I get the following error.

# docker run --rm -p 8888:8888 registry.cn.aliyuncs.com/children-data:1.0

WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64/v2) and no specific platform was requested
exec /cnb/process/web: exec format error
ChildrenGreens commented 4 months ago

@GeorgeJose7 You can refer to #38714 ,paketo-arm64 supports the ARM architecture.

scottfrederick commented 4 months ago

The requested image's platform (linux/arm64)

You have built an image for the ARM architecture, which will not run on a machine that has AMD/x86 architecture. This is what the exec format error message is indicating. We are working on an enhancement that will allow you to build images for architectures other than the architecture of the host machine, providing the host machine has the ability to emulate the other architecture (as is often the case with Macs using Rosetta).

ChildrenGreens commented 4 months ago

@scottfrederick I am looking forward to your enhanced features. I have already installed Rosetta.

lpellegr commented 3 months ago

Here is a simple Gradle configuration that works on amd64 and arm64 to build native images:

bootBuildImage {
    builder = 'paketobuildpacks/builder-jammy-buildpackless-tiny'
    buildpacks = ['paketobuildpacks/java-native-image']
}
Persi commented 3 months ago

Here is a simple Gradle configuration that works on amd64 and arm64 to build native images:

bootBuildImage {
    builder = 'paketobuildpacks/builder-jammy-buildpackless-tiny'
    buildpacks = ['paketobuildpacks/java-native-image']
}

Worked like a charm on my m2 :)