diff --git a/docker-plugin/src/main/java/io/micronaut/gradle/docker/NativeImageDockerfile.java b/docker-plugin/src/main/java/io/micronaut/gradle/docker/NativeImageDockerfile.java index fcaf4e2c..216a038f 100644 --- a/docker-plugin/src/main/java/io/micronaut/gradle/docker/NativeImageDockerfile.java +++ b/docker-plugin/src/main/java/io/micronaut/gradle/docker/NativeImageDockerfile.java @@ -724,7 +724,11 @@ private String resolve() { if (strategy == DockerBuildStrategy.LAMBDA && baseImage == null) { baseImage = "amazonlinux:2"; } else if (baseImage == null) { - baseImage = "frolvlad/alpine-glibc:alpine-" + DefaultVersions.ALPINE; + baseImage = getGraalArch() + .map(a -> a.equals(ARM_ARCH) + ? "cgr.dev/chainguard/wolfi-base:latest" + : "frolvlad/alpine-glibc:alpine-" + DefaultVersions.ALPINE) + .getOrElse("frolvlad/alpine-glibc:alpine-" + DefaultVersions.ALPINE); } return baseImage; diff --git a/functional-tests/src/test/groovy/io/micronaut/gradle/docker/DockerNativeFunctionalTest.groovy b/functional-tests/src/test/groovy/io/micronaut/gradle/docker/DockerNativeFunctionalTest.groovy index 6ba76d15..aeb58cbc 100644 --- a/functional-tests/src/test/groovy/io/micronaut/gradle/docker/DockerNativeFunctionalTest.groovy +++ b/functional-tests/src/test/groovy/io/micronaut/gradle/docker/DockerNativeFunctionalTest.groovy @@ -12,6 +12,12 @@ import spock.lang.Requires @IgnoreIf({ os.windows }) class DockerNativeFunctionalTest extends AbstractEagerConfiguringFunctionalTest { + @Lazy + String defaultBaseImage = { -> System.properties['os.arch'] == "aarch64" ? 'cgr.dev/chainguard/wolfi-base:latest' : "frolvlad/alpine-glibc:alpine-${DefaultVersions.ALPINE}" }() + + @Lazy + String defaultDockerFrom = { -> "FROM $defaultBaseImage" + (System.properties['os.arch'] == "aarch64" ? '' : '\nRUN apk --no-cache update && apk add libstdc++') }() + def "test build docker native image for runtime #runtime"() { given: settingsFile << "rootProject.name = 'hello-world'" @@ -192,7 +198,7 @@ micronaut: dockerfileNativeTask.outcome == TaskOutcome.SUCCESS and: - dockerFileNative.find { s -> s.contains('FROM frolvlad/alpine-glibc:alpine-') } + dockerFileNative.find { s -> s.contains(defaultBaseImage) } dockerFileNative.find { s -> !s.contains('-H:+StaticExecutableWithDynamicLibC') } } @@ -587,8 +593,7 @@ RUN mkdir -p /home/alternate/config-dirs/io.netty/netty-common/4.0.0.Final COPY config-dirs/generateResourcesConfigFile /home/alternate/config-dirs/generateResourcesConfigFile COPY config-dirs/io.netty/netty-common/4.0.0.Final /home/alternate/config-dirs/io.netty/netty-common/4.0.0.Final RUN native-image --exclude-config .*/libs/netty-transport-4.0.0.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-buffer-4.0.0.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http2-4.0.0.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http-4.0.0.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-common-4.0.0.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-handler-4.0.0.Final.jar ^/META-INF/native-image/.* -cp /home/alternate/libs/*.jar:/home/alternate/resources:/home/alternate/application.jar --no-fallback -o application -H:ConfigurationFileDirectories=/home/alternate/config-dirs/generateResourcesConfigFile,/home/alternate/config-dirs/io.netty/netty-buffer/4.0.0.Final,/home/alternate/config-dirs/io.netty/netty-common/4.0.0.Final,/home/alternate/config-dirs/io.netty/netty-codec-http/4.0.0.Final,/home/alternate/config-dirs/io.netty/netty-transport/4.0.0.Final,/home/alternate/config-dirs/io.netty/netty-handler/4.0.0.Final,/home/alternate/config-dirs/io.netty/netty-codec-http2/4.0.0.Final example.Application -FROM frolvlad/alpine-glibc:alpine-${DefaultVersions.ALPINE} -RUN apk --no-cache update && apk add libstdc++ +${defaultDockerFrom} EXPOSE 8080 HEALTHCHECK CMD curl -s localhost:8090/health | grep '"status":"UP"' COPY --from=graalvm /home/alternate/application /app/application @@ -711,8 +716,7 @@ RUN mkdir /home/app/config-dirs RUN mkdir -p /home/app/config-dirs/generateResourcesConfigFile 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 -o application -H:ConfigurationFileDirectories=/home/app/config-dirs/generateResourcesConfigFile example.Application -FROM frolvlad/alpine-glibc:alpine-${DefaultVersions.ALPINE} -RUN apk --no-cache update && apk add libstdc++ +${defaultDockerFrom} EXPOSE 8080 COPY --from=graalvm /home/app/application /app/application ENTRYPOINT ["/app/application"] diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 963c7456..1840e422 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -1056,6 +1056,9 @@ dockerfileNative { } ---- +The compiled native binary will ultimately be copied into an `alpine-glibc` base image for X86_64, and `cgr.dev/chainguard/wolfi-base` for ARM. +These base images can be overridden via configuration see <<_base_image_and_pull_limits>> and <<_build_mostly_static_native_executables>>. + ===== Base image and pull limits By default, the plugin will use amazonlinux pulled from Docker Hub as a base image for GraalVM native AWS Lambda executables.