Search code examples
spring-bootspring-boot-maven-pluginhealth-checkpaketo

How to run health check with Spring Boot 3.4?


I upgraded my application to Spring Boot 3.4 and the health check is not working anymore. What do I need to change to make the health check work again?

Logs

If I call docker container inspect, I see following logs for the healt check:

"Health": {
     "Status": "unhealthy",
     "FailingStreak": 6,
     "Log": [
         {
             "Start": "2025-02-10T09:12:40.658415283Z",
             "End": "2025-02-10T09:12:40.716595544Z",
             "ExitCode": -1,
             "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"/bin/sh\": stat /bin/sh: no such file or directory: unknown"
         },

Configuration

<configuration>
    <image>
        <env>
            <BP_SPRING_CLOUD_BINDINGS_DISABLED>true</BP_SPRING_CLOUD_BINDINGS_DISABLED>
            <BP_HEALTH_CHECKER_ENABLED>true</BP_HEALTH_CHECKER_ENABLED>
            <BPE_LANG>en_US.UTF-8</BPE_LANG>​
        </env>
        <buildpacks>
            <buildpack>gcr.io/paketo-buildpacks/adoptium</buildpack>
            <buildpack>urn:cnb:builder:paketo-buildpacks/java</buildpack>
            <buildpack>gcr.io/paketo-buildpacks/health-checker:latest</buildpack>
        </buildpacks>
        <createdDate>${maven.build.timestamp}</createdDate>
    </image>
</configuration>
<goals>
    <goal>build-image-no-fork</goal>
</goals>

Command

I added to my docker container run command the health check parameters:

      --health-cmd /workspace/health-check
      --health-interval 1m
      --env THC_PORT=8081
      --env THC_PATH=/health

See also: How to set THC_PORT and THC_PATH with Spring Boot 3.3?

Research

I read Spring Boot 3.4 Release Notes:

Paketo tiny Builder for Building OCI Images

The default Cloud Native Buildpacks builder used when building OCI images for JVM applications using the Maven spring-boot:build-image goal or Gradle bootBuildImage task has changed from paketobuildpacks/builder-jammy-base to paketobuildpacks/builder-jammy-java-tiny. This should result in smaller images. The tiny builder does not include a shell, so it might not work for applications that require a start script to run the application. It also includes a reduced set of system libraries which, depending on your application, may not meet its needs. See the Maven or Gradle documentation for information on customizing the builder.

So there is no shell in the image anymore. That matches the logs.

I read Packaging OCI Images, but I don't understand, what I have to change.

Question

What do I need to change in my Spring Boot Maven configuration to make the health check work again?


Solution

  • This looks like a limitation on the docker run --health-cmd flag. From what I can tell, it sets the command to be run in a shell, even though that's not required here. See https://github.com/docker/cli/issues/3719. The best bet would be the workaround that you mentioned in your answer @dur.

    The only way to not have it use a shell at the moment seems to be to use the HEALTHCHECK argument in a Dockerfile.

    Another possible workaround would be to wrap your buildpack produced image in a Dockerfile with this:

    FROM <buildpacks-img>
    
    HEALTHCHECK --interval=5s CMD ["/workspace/health-check"]
    

    That would embed the health check info into the image itself and because it's using the [ .. ] syntax, Docker will not use a shell to launch the health check command.