I've been trying to generate a Spring Boot image using buildpacks.
I generated the project using https://start.spring.io/ with this configuration .
I only added a controller to get some response from the server:
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
And configured gradle to use paketobuildpacks/builder-jammy-base:latest
tasks.named("bootBuildImage") {
builder = "paketobuildpacks/builder-jammy-base:latest"
}
If I build this image using ./gradlew bootBuildImage
everything works great.
But if I try to use pack
I get a 404 from tomcat when trying to get to /
.
$ pack build springboot-demo --builder=paketobuildpacks/builder-jammy-base:latest
$ docker run -p 8080:8080 springboot-demo
Calculating JVM memory based on 3593560K 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 -Xmx2986909K -XX:MaxMetaspaceSize=94650K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 3593560K, Thread Count: 250, Loaded Class Count: 14297, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -XX:+ExitOnOutOfMemoryError -XX:MaxDirectMemorySize=10M -Xmx2986909K -XX:MaxMetaspaceSize=94650K -XX:ReservedCodeCacheSize=240M -Xss1M -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics
[CONTAINER] org.apache.coyote.http11.Http11NioProtocol INFO Initializing ProtocolHandler ["http-nio-8080"]
[CONTAINER] org.apache.catalina.startup.Catalina INFO Server initialization in [570] milliseconds
[CONTAINER] org.apache.catalina.core.StandardService INFO Starting service [Catalina]
[CONTAINER] org.apache.catalina.core.StandardEngine INFO Starting Servlet engine: [Apache Tomcat/9.0.89]
[CONTAINER] org.apache.catalina.startup.HostConfig INFO Deploying web application directory [/workspace/demo-0.0.1-SNAPSHOT]
[CONTAINER] org.apache.tomcat.util.descriptor.web.WebXml WARNING Unknown version string [5.0]. Default version will be used.
[CONTAINER] org.apache.jasper.servlet.TldScanner INFO At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
[CONTAINER] org.apache.catalina.startup.HostConfig INFO Deployment of web application directory [/workspace/demo-0.0.1-SNAPSHOT] has finished in [1,393] ms
[CONTAINER] org.apache.catalina.startup.HostConfig INFO Deploying web application directory [/workspace/demo-0.0.1-SNAPSHOT-plain]
[CONTAINER] org.apache.tomcat.util.descriptor.web.WebXml WARNING Unknown version string [5.0]. Default version will be used.
[CONTAINER] org.apache.jasper.servlet.TldScanner INFO At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
[CONTAINER] org.apache.catalina.startup.HostConfig INFO Deployment of web application directory [/workspace/demo-0.0.1-SNAPSHOT-plain] has finished in [837] ms
[CONTAINER] org.apache.coyote.http11.Http11NioProtocol INFO Starting ProtocolHandler ["http-nio-8080"]
[CONTAINER] org.apache.catalina.startup.Catalina INFO Server startup in [2276] milliseconds
I can see that the buildpacks participating in the build are different:
For bootBuildImage
:
[creator] paketo-buildpacks/ca-certificates 3.7.0
[creator] paketo-buildpacks/bellsoft-liberica 10.7.2
[creator] paketo-buildpacks/syft 1.46.0
[creator] paketo-buildpacks/executable-jar 6.9.0
[creator] paketo-buildpacks/dist-zip 5.7.0
[creator] paketo-buildpacks/spring-boot 5.29.1
For pack build
:
[detector] paketo-buildpacks/ca-certificates 3.7.0
[detector] paketo-buildpacks/bellsoft-liberica 10.7.2
[detector] paketo-buildpacks/syft 1.46.0
[detector] paketo-buildpacks/gradle 7.10.0
[detector] paketo-buildpacks/executable-jar 6.9.0
[detector] paketo-buildpacks/apache-tomcat 8.0.0
[detector] paketo-buildpacks/apache-tomee 1.9.0
[detector] paketo-buildpacks/liberty 4.1.0
[detector] paketo-buildpacks/dist-zip 5.7.0
[detector] paketo-buildpacks/spring-boot 5.29.1
How can I have pack build
behave the same way as the gradle command?
I don't fully understand why, but disabling the war generation makes the image work.
war {
enabled = false
}
Adding that to build.gradle
fixed the issue.
Running:
pack build springboot-demo --builder=paketobuildpacks/builder-jammy-base:latest
Generates a working image.