Open maradanasai opened 5 months ago
We do have ARM64 support. It is new and not totally complete across all buildpacks at this point in time. You're using Java buildpacks and those are all updated, so you should be OK.
The trick at this point is that you need to use a specific builder. Not all of the Paketo builders support ARM64.
The builder you want to use is paketobuildpacks/builder-jammy-buildpackless-tiny
.
The other point to note is that this is a "buildpackless" builder, so there are no buildpacks installed on the builder by default. This is intentional, but it means you need to supply a list of buildpacks you want to use when you perform your build.
With pack build
this is done with the -b
flag (you can set multiple).
With the Spring Boot build tools, check out the previous two links above for steps to set buildpacks too.
To confirm it's building arm64, watch the build output and look at the JVM it's installing. You should see it install an ARM64 compatible-JVM.
For what it's worth, there is no cross-compilation support with either pack or Spring Boot build tools. So if you want an ARM64 image, you need to build on a Mac m-series machine, an ARM64 VM or some other ARM64 system.
Hope that helps!
Hi @dmikusa Thanks for getting back. After making changes as mentioned, seeing following errors docker run logs
docker logs -f 219d467cfa683eacd81bbc7e3bfe2a40924949592b27b6d6f9d0b28820a3deb3
ERROR: failed to launch: exec.d: failed to execute exec.d file at path '/layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper': fork/exec /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper: exec format error
build config
tasks.named("bootBuildImage") {
environment["BP_JVM_VERSION"] = "21"
environment["BP_JVM_CDS_ENABLED"] = "true"
builder = "paketobuildpacks/builder-jammy-buildpackless-tiny"
buildpacks = [ "gcr.io/paketo-buildpacks/java" ]
}
bootbuildImage logs
Executing 'bootBuildImage'...
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :resolveMainClassName UP-TO-DATE
> Task :bootJar UP-TO-DATE
> Task :bootBuildImage
Building image 'docker.io/library/test-counter-resets:0.0.1-SNAPSHOT'
> Pulling builder image 'docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny:latest' ..................................................
> Pulled builder image 'paketobuildpacks/builder-jammy-buildpackless-tiny@sha256:5ae4709eca3c7c712533704a073e180a2f4c317e34d5b1a827ac04231cd45e7a'
> Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' ..................................................
> Pulled run image 'paketobuildpacks/run-jammy-tiny@sha256:4e3822b34116cbd0ffdac7d99f219be39cc48faf4257c102ed6312f0d47195ff'
> Pulling buildpack image 'gcr.io/paketo-buildpacks/java:latest' ..................................................
> Pulled buildpack image 'gcr.io/paketo-buildpacks/java@sha256:6c7a6dd99eb7cbd6785134636a460e57a65b208860e780e5f5a4468369212e80'
> Executing lifecycle version v0.19.7
> Using build cache volume 'pack-cache-4f3fd4f663c7.build'
> Running creator
[creator] ===> ANALYZING
[creator] Restoring data for SBOM from previous image
[creator] ===> DETECTING
[creator] target distro name/version labels not found, reading /etc/os-release file
[creator] 6 of 26 buildpacks participating
[creator] paketo-buildpacks/ca-certificates 3.8.0
[creator] paketo-buildpacks/bellsoft-liberica 10.8.0
[creator] paketo-buildpacks/syft 1.47.0
[creator] paketo-buildpacks/executable-jar 6.10.0
[creator] paketo-buildpacks/dist-zip 5.8.0
[creator] paketo-buildpacks/spring-boot 5.30.0
[creator] ===> RESTORING
[creator] Restoring metadata for "paketo-buildpacks/ca-certificates:helper" from app image
[creator] Restoring metadata for "paketo-buildpacks/bellsoft-liberica:helper" from app image
[creator] Restoring metadata for "paketo-buildpacks/bellsoft-liberica:java-security-properties" from app image
[creator] Restoring metadata for "paketo-buildpacks/bellsoft-liberica:jre" from app image
[creator] Restoring metadata for "paketo-buildpacks/syft:syft" from cache
[creator] Restoring metadata for "paketo-buildpacks/spring-boot:spring-cloud-bindings" from app image
[creator] Restoring metadata for "paketo-buildpacks/spring-boot:web-application-type" from app image
[creator] Restoring metadata for "paketo-buildpacks/spring-boot:helper" from app image
[creator] Restoring data for "paketo-buildpacks/bellsoft-liberica:jre" from cache
[creator] Restoring data for "paketo-buildpacks/syft:syft" from cache
[creator] Restoring data for "paketo-buildpacks/spring-boot:spring-cloud-bindings" from cache
[creator] Restoring data for SBOM from cache
[creator] ===> BUILDING
[creator] target distro name/version labels not found, reading /etc/os-release file
[creator]
[creator] Paketo Buildpack for CA Certificates 3.8.0
[creator] https://github.com/paketo-buildpacks/ca-certificates
[creator] Launch Helper: Reusing cached layer
[creator]
[creator] Paketo Buildpack for BellSoft Liberica 10.8.0
[creator] https://github.com/paketo-buildpacks/bellsoft-liberica
[creator] Build Configuration:
[creator] $BP_JVM_JLINK_ARGS --no-man-pages --no-header-files --strip-debug --compress=1 configure custom link arguments (--output must be omitted)
[creator] $BP_JVM_JLINK_ENABLED false enables running jlink tool to generate custom JRE
[creator] $BP_JVM_TYPE JRE the JVM type - JDK or JRE
[creator] $BP_JVM_VERSION 21 the Java version
[creator] Launch Configuration:
[creator] $BPL_DEBUG_ENABLED false enables Java remote debugging support
[creator] $BPL_DEBUG_PORT 8000 configure the remote debugging port
[creator] $BPL_DEBUG_SUSPEND false configure whether to suspend execution until a debugger has attached
[creator] $BPL_HEAP_DUMP_PATH write heap dumps on error to this path
[creator] $BPL_JAVA_NMT_ENABLED true enables Java Native Memory Tracking (NMT)
[creator] $BPL_JAVA_NMT_LEVEL summary configure level of NMT, summary or detail
[creator] $BPL_JFR_ARGS configure custom Java Flight Recording (JFR) arguments
[creator] $BPL_JFR_ENABLED false enables Java Flight Recording (JFR)
[creator] $BPL_JMX_ENABLED false enables Java Management Extensions (JMX)
[creator] $BPL_JMX_PORT 5000 configure the JMX port
[creator] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation
[creator] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation
[creator] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation
[creator] $JAVA_TOOL_OPTIONS the JVM launch flags
[creator] Using Java version 21 from BP_JVM_VERSION
[creator] BellSoft Liberica JRE 21.0.3: Contributing to layer
[creator] Downloading from https://github.com/bell-sw/Liberica/releases/download/21.0.3+12/bellsoft-jre21.0.3+12-linux-aarch64.tar.gz
[creator] Verifying checksum
[creator] Expanding to /layers/paketo-buildpacks_bellsoft-liberica/jre
[creator] Adding 137 container CA certificates to JVM truststore
[creator] Writing env.build/JAVA_HOME.default
[creator] Writing env.build/JRE_HOME.default
[creator] Writing env.launch/BPI_APPLICATION_PATH.default
[creator] Writing env.launch/BPI_JVM_CACERTS.default
[creator] Writing env.launch/BPI_JVM_CLASS_COUNT.default
[creator] Writing env.launch/BPI_JVM_SECURITY_PROVIDERS.default
[creator] Writing env.launch/JAVA_HOME.default
[creator] Writing env.launch/JAVA_TOOL_OPTIONS.append
[creator] Writing env.launch/JAVA_TOOL_OPTIONS.delim
[creator] Writing env.launch/MALLOC_ARENA_MAX.default
[creator] Launch Helper: Reusing cached layer
[creator] Java Security Properties: Reusing cached layer
[creator]
[creator] Paketo Buildpack for Syft 1.47.0
[creator] https://github.com/paketo-buildpacks/syft
[creator] Downloading from https://github.com/anchore/syft/releases/download/v0.105.1/syft_0.105.1_linux_arm64.tar.gz
[creator] Verifying checksum
[creator] Writing env.build/SYFT_CHECK_FOR_APP_UPDATE.default
[creator]
[creator] Paketo Buildpack for Executable JAR 6.10.0
[creator] https://github.com/paketo-buildpacks/executable-jar
[creator] Command "packages" is deprecated, use `syft scan` instead
[creator] Class Path: Contributing to layer
[creator] Writing env/CLASSPATH.delim
[creator] Writing env/CLASSPATH.prepend
[creator] Process types:
[creator] executable-jar: java org.springframework.boot.loader.launch.JarLauncher (direct)
[creator] task: java org.springframework.boot.loader.launch.JarLauncher (direct)
[creator] web: java org.springframework.boot.loader.launch.JarLauncher (direct)
[creator]
[creator] Paketo Buildpack for Spring Boot 5.30.0
[creator] https://github.com/paketo-buildpacks/spring-boot
[creator] Build Configuration:
[creator] $BPL_JVM_CDS_ENABLED false whether to enable CDS optimizations at runtime
[creator] $BPL_SPRING_AOT_ENABLED false whether to enable Spring AOT at runtime
[creator] $BP_JVM_CDS_ENABLED true whether to enable CDS & perform JVM training run
[creator] $BP_SPRING_AOT_ENABLED false whether to enable Spring AOT
[creator] $BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support
[creator] $BP_SPRING_CLOUD_BINDINGS_VERSION 1 default version of Spring Cloud Bindings library to contribute
[creator] Launch Configuration:
[creator] $BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings
[creator] $BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings
[creator] Spring Cloud Bindings 2.0.3: Reusing cached layer
[creator] Performance: Contributing to layer
[creator] Extracting Jar
[creator] . ____ _ __ _ _
[creator] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
[creator] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
[creator] \\/ ___)| |_)| | | | | || (_| | ) ) ) )
[creator] ' |____| .__|_| |_|_| |_\__, | / / / /
[creator] =========|_|==============|___/=/_/_/_/
[creator]
[creator] :: Spring Boot :: (v3.3.0)
[creator]
[creator] 2024-06-21T16:06:36.964Z INFO 182 --- [test-counter-resets] [ main] c.e.t.TestCounterResetsApplication : Starting TestCounterResetsApplication v0.0.1-SNAPSHOT using Java 21.0.3 with PID 182 (/workspace/runner.jar started by cnb in /workspace)
[creator] 2024-06-21T16:06:36.966Z INFO 182 --- [test-counter-resets] [ main] c.e.t.TestCounterResetsApplication : No active profile set, falling back to 1 default profile: "default"
[creator] 2024-06-21T16:06:37.974Z INFO 182 --- [test-counter-resets] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8083 (http)
[creator] 2024-06-21T16:06:37.983Z INFO 182 --- [test-counter-resets] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
[creator] 2024-06-21T16:06:37.983Z INFO 182 --- [test-counter-resets] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.24]
[creator] 2024-06-21T16:06:38.011Z INFO 182 --- [test-counter-resets] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
[creator] 2024-06-21T16:06:38.012Z INFO 182 --- [test-counter-resets] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1009 ms
[creator] 2024-06-21T16:06:38.413Z INFO 182 --- [test-counter-resets] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 4 endpoints beneath base path '/actuator'
[creator] [2.083s][warning][cds] Preload Warning: Verification failed for org.springframework.core.ReactiveAdapterRegistry$ReactorAdapter
[creator] [2.101s][warning][cds] Preload Warning: Verification failed for org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer
[creator] [2.102s][warning][cds] Preload Warning: Verification failed for org.springframework.boot.actuate.autoconfigure.observation.web.client.WebClientObservationConfiguration
[creator] [2.107s][warning][cds] Preload Warning: Verification failed for org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
[creator] [2.107s][warning][cds] Preload Warning: Verification failed for org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
[creator] [2.110s][warning][cds] Preload Warning: Verification failed for org.springframework.http.codec.multipart.DefaultPartHttpMessageReader
[creator] [2.112s][warning][cds] Preload Warning: Verification failed for io.micrometer.core.instrument.binder.logging.Log4j2Metrics
[creator] [2.141s][warning][cds] Preload Warning: Verification failed for org.springframework.boot.logging.log4j2.Log4J2LoggingSystem
[creator] [2.160s][warning][cds] Preload Warning: Verification failed for org.springframework.web.servlet.view.freemarker.FreeMarkerView
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy59: Unsupported location
[creator] [2.166s][warning][cds] Skipping com/example/test_counter_resets/TestCounterResetsApplication$$SpringCGLIB$$0: Unsupported location
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy33: Unsupported location
[creator] [2.166s][warning][cds] Skipping org/springframework/core/ReactiveAdapterRegistry$ReactorAdapter: Failed verification
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy68: Unsupported location
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy23: Unsupported location
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy81: Unsupported location
[creator] [2.166s][warning][cds] Skipping jdk/proxy2/$Proxy24: Unsupported location
[creator] [2.166s][warning][cds] Skipping org/springframework/boot/actuate/autoconfigure/web/server/$Proxy69: Unsupported location
[creator] [2.166s][warning][cds] Skipping org/springframework/core/$Proxy55: Unsupported location
[creator] [2.166s][warning][cds] Skipping jdk/internal/event/ThreadSleepEvent: JFR event class
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy73: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy80: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy37: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy70: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy46: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy29: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy7: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy25: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy39: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy5: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy42: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy76: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy12: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy1/$Proxy1: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy65: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy34: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy77: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy74: Unsupported location
[creator] [2.167s][warning][cds] Skipping org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration: Failed verification
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy11: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy22: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy56: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy79: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy40: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy1/$Proxy8: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy60: Unsupported location
[creator] [2.167s][warning][cds] Skipping org/springframework/boot/autoconfigure/cache/InfinispanCacheConfiguration: Failed verification
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy66: Unsupported location
[creator] [2.167s][warning][cds] Skipping org/springframework/web/servlet/view/freemarker/FreeMarkerView: Failed verification
[creator] [2.167s][warning][cds] Skipping org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration: Failed verification
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy53: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy28: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy18: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy1/$Proxy9: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy67: Unsupported location
[creator] [2.167s][warning][cds] Skipping org/springframework/core/$Proxy6: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy43: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy31: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy82: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy54: Unsupported location
[creator] [2.167s][warning][cds] Skipping jdk/proxy2/$Proxy2: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy20: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy35: Unsupported location
[creator] [2.168s][warning][cds] Skipping io/micrometer/core/instrument/binder/logging/Log4j2Metrics: Failed verification
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy17: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy44: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy21: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy1/$Proxy0: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy1/$Proxy3: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy10: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy26: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy45: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy48: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy78: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy27: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy1/$Proxy4: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy47: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy50: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/internal/event/Event: JFR event class
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy30: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy41: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy63: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy72: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy1/$Proxy75: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy62: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy51: Unsupported location
[creator] [2.168s][warning][cds] Skipping org/springframework/http/codec/multipart/DefaultPartHttpMessageReader: Failed verification
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy15: Unsupported location
[creator] [2.168s][warning][cds] Skipping com/sun/proxy/jdk/proxy1/$Proxy71: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy61: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy52: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy36: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy32: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy38: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy64: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy57: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy16: Unsupported location
[creator] [2.168s][warning][cds] Skipping org/springframework/boot/logging/log4j2/Log4J2LoggingSystem: Failed verification
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy13: Unsupported location
[creator] [2.168s][warning][cds] Skipping org/springframework/core/$Proxy58: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/internal/event/SecurityProviderServiceEvent: JFR event class
[creator] [2.168s][warning][cds] Skipping jdk/proxy1/$Proxy19: Unsupported location
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy49: Unsupported location
[creator] [2.168s][warning][cds] Skipping org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer: Failed verification
[creator] [2.168s][warning][cds] Skipping jdk/proxy2/$Proxy14: Unsupported location
[creator] Writing env.launch/BPL_JVM_CDS_ENABLED.default
[creator] Writing env.launch/BPL_SPRING_AOT_ENABLED.default
[creator] Web Application Type: Reusing cached layer
[creator] Launch Helper: Reusing cached layer
[creator] Image labels:
[creator] org.opencontainers.image.title
[creator] org.opencontainers.image.version
[creator] org.springframework.boot.version
[creator] Process types:
[creator] spring-boot-app: java -cp runner.jar:lib/spring-cloud-bindings-2.0.3.jar com.example.test_counter_resets.TestCounterResetsApplication (direct)
[creator] task: java -cp runner.jar:lib/spring-cloud-bindings-2.0.3.jar com.example.test_counter_resets.TestCounterResetsApplication (direct)
[creator] web: java -cp runner.jar:lib/spring-cloud-bindings-2.0.3.jar com.example.test_counter_resets.TestCounterResetsApplication (direct)
[creator] ===> EXPORTING
[creator] Reusing layer 'paketo-buildpacks/ca-certificates:helper'
[creator] Reusing layer 'paketo-buildpacks/bellsoft-liberica:helper'
[creator] Reusing layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[creator] Reusing layer 'paketo-buildpacks/executable-jar:classpath'
[creator] Adding layer 'paketo-buildpacks/spring-boot:Performance'
[creator] Reusing layer 'paketo-buildpacks/spring-boot:helper'
[creator] Reusing layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[creator] Reusing layer 'paketo-buildpacks/spring-boot:web-application-type'
[creator] Adding layer 'buildpacksio/lifecycle:launch.sbom'
[creator] Adding 1/1 app layer(s)
[creator] Adding layer 'buildpacksio/lifecycle:launcher'
[creator] Reusing layer 'buildpacksio/lifecycle:config'
[creator] Reusing layer 'buildpacksio/lifecycle:process-types'
[creator] Adding label 'io.buildpacks.lifecycle.metadata'
[creator] Adding label 'io.buildpacks.build.metadata'
[creator] Adding label 'io.buildpacks.project.metadata'
[creator] Adding label 'org.opencontainers.image.title'
[creator] Adding label 'org.opencontainers.image.version'
[creator] Adding label 'org.springframework.boot.version'
[creator] Setting default process type 'web'
[creator] Saving docker.io/library/test-counter-resets:0.0.1-SNAPSHOT...
[creator] *** Images (e341cfeab740):
[creator] docker.io/library/test-counter-resets:0.0.1-SNAPSHOT
[creator] Adding cache layer 'paketo-buildpacks/bellsoft-liberica:jre'
[creator] Adding cache layer 'paketo-buildpacks/syft:syft'
[creator] Reusing cache layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[creator] Adding cache layer 'buildpacksio/lifecycle:cache.sbom'
Successfully built image 'docker.io/library/test-counter-resets:0.0.1-SNAPSHOT'
BUILD SUCCESSFUL in 1m 19s
5 actionable tasks: 1 executed, 4 up-to-date
9:36:49 pm: Execution finished 'bootBuildImage'.
Can you please take a look? problem is my cicd runners are on both ARM64 & AMD64 machines (same about my deployment servers). so if there is no cross-compilation support i.e. not generate multi-arch builds, it will surely fail on releases. Can you please provide workarounds for this? many thanks
First thing, you've got some layers that were cached. Usually, caching is good and makes things faster. But in this case, it's not updating those cached layers with ARM64 binaries. I'll open a bug for that, cause it should consider the architecture in that caching decision, but for now, just delete your existing app images and the build cache.
> Using build cache volume 'pack-cache-4f3fd4f663c7.build'
or you can change the image name, that will trigger a fresh build too.
I suspect that's going to fix your issue here. It'll give you a build that's consistently all arm64.
To your other question, what you can do is to build twice. Once for each architecture. Push those images to a registry as separate images. Then you can use the docker manifest
to create an image manifest with those two images. Then you publish the manifest image and have your deployment servers pull the manifest image.
I'm hoping that in the future we'll have some support for that in pack build
, but it's difficult because not every buildpack can cross-compile code. For Java apps it's simple, but for other types of apps it might not be as easy. You might need special tools or you might just have to run on separate hardware/VMs. Java native-image is in that boat presently. There's no cross-compile support in the tool, so you just need separate hardware/VMs to build that code.
Thanks for checking and providing insights @dmikusa . I saw something related to this here https://github.com/buildpacks/pack/issues/1570 and hopping this can be adopted
Any update on this? I'd like to switch from
docker buildx build --platform linux/amd64,linux/arm64 --push .
to mvn spring-boot:build-image
but I cannot find a way to build images (ultimate goal native images) for multiple platform and push them as a single tagged manifest to the registry (as buildx
does).
@heruan Please try Spring Boot 3.4.0. That was recently released and I believe that fixes up the boot build tools to work with multi-platform.
@dmikusa thanks! I'm testing Spring Boot 3.4.0 and there is a new imagePlatform
attribute but it seems like it works for one platform at a time.
I can build images for both platforms with different tags running spring-boot:build-image
multiple times (once for each platform), push them individually, then create and tag a single multi platform manifest — but then I have three different tags in the registry while with buildx
a single tag is pushed. Would be great to achieve the same with Spring Boot!
@heruan Neither pack build
nor spring-boot:build-image
will build images for multiple architectures in one run. That may be something that comes in the future, but it's not clear how that should work, especially when there is native code involved (emulation would be required).
For now, what you can do is build the two images independently and then use a command like docker manifest
to make an index image from the two.
If you have a minute and are able to share anything about your use case that would be appreciated. I've been trying to understand how folks are using the tool and building images to help shape how things work in the future. For example, what's your build environment/CI? What type of application are you building? Is it server/data center deployed? Is it used on end-user devices? or deployed by a variety of different people? How do multiple architectures come into play when you or your users are running the generated app image?
@dmikusa sure, and thank you for the interest on this topic! The image is a Kubernetes Operator built with Spring Boot and the Java Operator SDK as a Maven project. Both architectures are needed since the image is public and might be pulled on AMD or ARM platforms.
The image is built during a GitHub Actions workflow running:
docker buildx build --platform linux/amd64,linux/arm64 --tag foo/bar:baz --push .
Result of this command is a single tag (baz
) pushed to Docker Hub providing images for both architectures, i.e. the foo/bar
repository gets a single new tag for each workflow run.
I'd like to keep this behavior, so that I get a single tag pushed for both architectures.
With Spring Boot, I'm able to run:
mvn spring-boot:build-image -Dspring-boot.build-image.imagePlatform=linux/amd64 -Dspring-boot.build-image.imageName=foo/bar:amd64
mvn spring-boot:build-image -Dspring-boot.build-image.imagePlatform=linux/arm64 -Dspring-boot.build-image.imageName=foo/bar:arm64
and get two images with two different tags, one per platform. At this point, I can push the two tagged images to Docker Hub and then create a foo/bar:baz
manifest that references both images. Great, but I get three tags on the repository for each release, and I'd prefer to avoid that. Note: you can't create a manifest if the images are not pushed to the registry first.
I don't know how docker buildx build
manages to build images for both platforms and push them with a single tag, but it's very convenient.
Ultimately, I'd like to switch to native images and building with Spring Boot and Paketo makes this very easy! I'm not looking for a single command but rather a single tag to get the images published.
Great, but I get three tags on the repository for each release, and I'd prefer to avoid that. Note: you can't create a manifest if the images are not pushed to the registry first.
Have you tried removing those tags after you publish the multi-arch image?
My understanding is that the container that the index manifest points to needs to exist, but it doesn't need to be tagged. The index should reference the sha hash digest of the images it points to, not the tags. So if you remove the tag, it shouldn't break the index manifest image.
We use pack for publishing multi-arch buildpacks & stacks. It handles the multi-arch image generation for us, but we don't end up with stray tagged images. I believe that's how it accomplishes this.
The other thing you can do is push your intermediate images to https://ttl.sh or a local registry (maybe only exists in your CI job) and then copy the final manifest image out to Docker Hub. We you copy that out, if you use a tool like crane, it should handle moving everything that's needed for the index image to work correctly.
Ultimately, I'd like to switch to native images and building with Spring Boot and Paketo makes this very easy! I'm not looking for a single command but rather a single tag to get the images published.
That is where things get more difficult. With Java, it's not too hard to cross-compile images for you because the Java code is the same on both architectures, we just need to install different JVMs for each architecture. When you switch to native image, you can't do that anymore because native-image doesn't cross-compile. You need to introduce emulation. I think docker buildx
does that for you, but don't quote me on that, I'm not an expert with that tool by any means.
It's possible that pack could do something similar, but pack is not as integrated with the OS as Docker, so it gets tricky. Do we require something like QEMU? Do we require users to configure that? Does pack take on the responsibility of bundling and setting that up? Can we do that inside a container, so the host OS doesn't require it? Aside from that, performance would be the next concern. Native image compiled in QEMU is like 40x slower (unscientific guesstimate), and it's fairly slow to begin with (IMHO).
My guess, at least short term, is the recommendation is going to be to do something like a matrix-style CI build of your different arch images, then stuff them into an index manifest for end-user consumption. Hopefully, we can smooth that out a bit though, and maybe create a way to do that without the intermediate tags.
Oh, I also forgot to mention the pack
cli has manifest support in it too. It's similar to what's in docker
. I suspect you'll have the same issues with tags as you do with Docker but it could be something to try.
> pack manifest -h
An image index is a higher-level manifest which points to specific image manifests and is ideal for one or more platforms; see: https://github.com/opencontainers/image-spec/ for more details
'pack manifest' commands provide tooling to create, update, or delete images indexes or push them to a remote registry.
'pack' will save a local copy of the image index at '$PACK_HOME/manifests'; the environment variable 'XDG_RUNTIME_DIR'
can be set to override the location, allowing manifests to be edited locally before being pushed to a registry.
These commands are experimental. For more information, consult the RFC which can be found at https://github.com/buildpacks/rfcs/blob/main/text/0124-pack-manifest-list-commands.md
Usage:
pack manifest [command]
Available Commands:
create Create a new manifest list.
add Add an image to a manifest list.
annotate Add or update information about an entry in a manifest list.
remove Remove one or more manifest lists from local storage
inspect Display information about a manifest list.
push Push a manifest list to a registry.
rm Remove an image manifest from a manifest list.
In mac M1, generated an image for testing SB 3.3 + CDS support using packeto buildpack which is part of bootBuildImage stage. This generated image is given following warning in mac M1 but able to run the app. But if I run the same image on cloud VM which is of type ARM64, it is giving following error and immediately existed with error
exec /cnb/process/web: exec format 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
Docker supports, multi arch build with specified arch types so wondering when this can be added to paketo build packs.