简体   繁体   中英

How to build a native-image Docker image that runs multiple architectures?

I would like to create a multi architecture Docker image containing the native-image binary of my Micronaut application.

When running ./gradlew dockerfileNative Micronaut generates a Dockerfile using a multi-staged build to create the native image of the Micronaut application. Usually the Dockerfile looks like this

FROM ghcr.io/graalvm/native-image:ol7-java17-22.2.0 AS graalvm
WORKDIR /home/app
COPY layers/libs /home/app/libs
COPY layers/classes /home/app/classes
COPY layers/resources /home/app/resources
COPY layers/application.jar /home/app/application.jar
RUN mkdir /home/app/config-dirs
COPY config-dirs/generateResourcesConfigFile /home/app/config-dirs/generateResourcesConfigFile
RUN native-image -cp /home/app/libs/*.jar:/home/app/resources:/home/app/application.jar --no-fallback -H:Name=application -J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.configure=ALL-UNNAMED -J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk=ALL-UNNAMED -J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jni=ALL-UNNAMED -J--add-exports=org.graalvm.sdk/org.graalvm.nativeimage.impl=ALL-UNNAMED -H:ConfigurationFileDirectories=/home/app/config-dirs/generateResourcesConfigFile -H:Class=ch.onstructive.salessystem.Application
FROM frolvlad/alpine-glibc:alpine-3.12
RUN apk --no-cache update && apk add libstdc++
EXPOSE 8080
HEALTHCHECK CMD curl -s localhost:8080/endpoints/health | grep '"status":"UP"'
COPY --from=graalvm /home/app/application /app/application
ENTRYPOINT ["/app/application"]

Micronaut uses ghcr.io/graalvm/native-image:ol7-java17-22.2.0 as the base image for the multi-stage build. Inspecting the base image on my MacBook M1, I see that the base image supports the arm64 architecture.

❯ docker image inspect --format "{{.RepoTags}} {{.Architecture}}" ghcr.io/graalvm/native-image:ol7-java17-22.2.0
[ghcr.io/graalvm/native-image:ol7-java17-22.2.0] arm64

In the second stage Micronaut uses frolvlad/alpine-glibc:alpine-3.12 and copies the native-image binary into it. The problem with this Docker image is, that it only supports amd64 and therefore cannot run on Mac M1 or other arm64 based systems.

❯ docker image inspect --format "{{.RepoTags}} {{.Architecture}}" frolvlad/alpine-glibc:alpine-3.12             
[frolvlad/alpine-glibc:alpine-3.12] amd64

Is there an alternative Docker image out there, that supports both arm64 (aka aarch64 ) and amd64 ?

I stumbled over a Docker image in the Micronaut Gradle Plugin documentation

tasks.named('dockerfileNative') {
    baseImage('gcr.io/distroless/cc-debian10')
}

This image works for both arm64 and amd64 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM