paketo-buildpacks / native-image

A Cloud Native Buildpack that creates native images from Java applications
Apache License 2.0
52 stars 9 forks source link

The manifest of is missing platform identifier #338

Closed Schaka closed 2 months ago

Schaka commented 2 months ago

First things first: I'm not quite sure if it's a bug or a feature request or if this even entirely the buildpack's fault, so I'll try to describe my scenario as good as I possibly can.

Currently, I am trying to get native arm64 images working for my app. Using QEMU via GitHub Actions, I am able to build both an amd64 and arm64 image.

To do so, I am using Spring-Boot's bootBuildImage and publish the image. This works perfectly. However, this obviously doesn't result in a multi-arch image and as far as I can tell, there isn't a way of building one (like this).

Now neither of the images' manifests contains a platform identifier at all. I was under the impression that this is meant to be set even for single images? As things stand right now, if the arm64 image gets published later and I pull the native-develop tag, it will pull an arm64 image even on x86 systems.

Is this correct/intended behavior?

I imagine there are ways I can work around this, like building images locally first and then trying to combine their manifests afterwards as part of the pipeline before publishing them (i.e. publish not handled by buildpack or Spring-Boot), but I wanted to check in first to see if this isn't something that's within the scope of this project instead.

dmikusa commented 2 months ago
  1. You might try pack and see if that includes a platform identifier. I believe that issue was fixed with pack. If that works correctly, then you'd need to open an issue up with the Boot team so that they're setting that as well. My understanding is that the platform implementation needs to handle this, not the actual buildpack implementations.

  2. Presently, neither pack nor Spring Boot Build Tools will allow you to build a multi-arch app image. The output will always be for a single arch, the one on which you've built. If you get the issue with platform resolved, you should be able to build them individually and then combine them for one single multi-arch image. I believe the docker manifest command allows you to do that.

The trouble with multi-arch app images in one shot is the actual build phase. Only Mac M-series machines can seamlessly build on both architectures, so without that you need QEMU or something like that to build on the separate images. That would be a lot for a tool like pack or SBBT to orchestrate.

My suggestion would be to reach out to the buildpacks.io team and discuss that though. Maybe open an issue here -> https://github.com/buildpacks/pack/issues. Put some details about your use case, what you'd like to do, how you're building the images now, how you're consuming the images, and how you think pack can make that workflow easier. That'll be a good way to get the conversation going.

Hope that helps!

Schaka commented 2 months ago

I ended up building both images separately and combining them into a single manifest in another build step. I'm not sure it would suit pack's mission to build multi-platform images by emulating other platforms or setting up QEMU to do so.

If anyone else comes across this issue, feel free to copy my build process and adjust to your needs: https://github.com/Schaka/janitorr/blob/main/.github/workflows/gradle.yml

dmikusa commented 2 months ago

Glad you were able to get that resolved & thanks so much for sharing your solution!