Skip to content

Commit

Permalink
Use an Arm compatible base image for Arm dockerBuildNative (#830)
Browse files Browse the repository at this point in the history
* Use an Arm compatible base image for Arm dockerBuildNative

For both Arm and X86 we are using an alpine base image.

There is no Arm variant of Alpine, so this builds an ARM native binary, then puts it in an x86 base image.

This change switches to use cgr.dev/chainguard/wolfi-base:latest when the architecture is Arm.

This image was chosen due to it's size... There may be a better default choice out there...

* Fix native tests for arm mac
  • Loading branch information
timyates authored Sep 14, 2023
1 parent c88872e commit c2341db
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'"
Expand Down Expand Up @@ -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') }
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"]
Expand Down
3 changes: 3 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit c2341db

Please sign in to comment.