javaspring-bootgraalvmbuildpack

Spring Boot Buildpacks with HealthCheck is breaking Native Image build process


I am trying to add healthchecks to my Spring Boot application while using Buildpacks as suggested in Spring Boot Build Image with Health Check.

My pom.xml configuration:

<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
</plugin>
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <image>
            <builder>dashaun/builder:tiny</builder>
            <name>${docker-image-name}</name>
            <env>
                <BP_HEALTH_CHECKER_ENABLED>true</BP_HEALTH_CHECKER_ENABLED>
            </env>
            <buildpacks>
                <buildpack>urn:cnb:builder:paketo-buildpacks/java</buildpack>
                <buildpack>gcr.io/paketo-buildpacks/health-checker:latest</buildpack>
            </buildpacks>
        </image>
    </configuration>
</plugin>

And my docker-compose.yml configuration:

  catalog-service:
    image: sivaprasadreddy/catalog-service
    container_name: catalog-service
    environment:
      - THC_PATH=/actuator/health
      - THC_PORT=8081
    ports:
      - "8081:8081"
    healthcheck:
      test: [ "CMD", "/cnb/process/health-check" ]
      start_period: 30s
      interval: 5s
      retries: 10

Now when I build the docker image using JVM build (mvn spring-boot:build-image) and run the container using docker-compose with the above-mentioned health check, it works fine.

Problem: The problem is when I try to build a GraalVM Native using mvn -Pnative spring-boot:build-image, it is not building a native image, instead it is building a regular jvm based image.

When I remove <buildpacks>...</buildpacks> config, it is properly building native image.

Should I include any additional buildpacks to support building native image or am I misconfiguring anything?


Solution

  • There is a different set of buildpacks required to run when you want to build a native image app. Because you're including a <buildpacks> block, you're specifically saying "use this set of buildpacks". That overrides the default selection, which would normally handle automatically selecting the right set of buildpacks (i.e. standard JVM or GraalVM).

    If you want to build a native image app, you'll need to switch the <buildpacks> block out, like this.

                <buildpacks>
                    <buildpack>urn:cnb:builder:paketo-buildpacks/java-native-image</buildpack>
                    <buildpack>gcr.io/paketo-buildpacks/health-checker:latest</buildpack>
                </buildpacks>
    

    Then make sure that you run ./mvnw spring-boot:build-image -Pnative with the native profile enabled. That's required as well.

    See the instructions in this sample for an example.