mockserver icon indicating copy to clipboard operation
mockserver copied to clipboard

ARM image doesn't include ARM binaries

Open EgorKulbachka opened this issue 3 years ago • 6 comments

Describe the issue Docker image 5.14.0 doesn't include ARM binaries inside the image.

The problem is that both docker images are built based on distroless java 17 which doesn't include ARM flavor, so java runtime include x86_64 binaries only.

You can verify that by running: docker manifest inspect --verbose mockserver/mockserver:5.14.0

It will give same layers for 2 architectures, sizes of the images are also exactly the same.

The easiest ways to solve this in my opinion:

  1. Change base image to something which supports multiple architectures (e.g. openjdk official build)
  2. Use different base images per architecture (example) and find new base image to use for ARM64 architectures.

What you are trying to do Prevent mockserver docker failures when running on ARM CPUs See #819 and #1428

MockServer version 5.14.0

To Reproduce Steps to reproduce the issue:

  1. Run AWS ARM instance (e.g. t4g.nano)
  2. Run mockserver from the dockerhub
[ec2-user@ip-172-31-0-105 ~]$ sudo docker run mockserver/mockserver:5.14.0
Unable to find image 'mockserver/mockserver:5.14.0' locally
6.14.0: Pulling from mockserver/mockserver
0a602d5f6ca3: Pull complete 
d7fbeaa2da3f: Pull complete 
a1f1879bb7de: Pull complete 
2afd560bd3d9: Pull complete 
8a4811140f89: Pull complete 
d72616bd414f: Pull complete 
004a8328e2b7: Pull complete 
Digest: sha256:59bf7fc611dc212f9fe07d316641bceec758f5db06df3d1ba9ac65e3569c805b
Status: Downloaded newer image for mockserver/mockserver:5.14.0
exec /usr/bin/java: exec format error

Mockserver fails to start with exec /usr/bin/java: exec format error

Expected behaviour Mockserver started successfully

MockServer Log n/a

EgorKulbachka avatar Dec 06 '22 11:12 EgorKulbachka

I just noticed that in Dockerfile mockserver also includes libnetty_tcnative_linux_x86_64.so so to make truly multiarch build there might be more changes needed to the actual build process, not only base image changes.

EgorKulbachka avatar Dec 06 '22 12:12 EgorKulbachka

After couple modifications I managed to build arm64 image which runs successfully on arm64 t4g.nano graviton instance. Main changes:

  • based on architecture on underlying system I am downloading either x64_64 or aarch64 netty-tcnative-boringssl-static.jar
    • netty-tcnative-2.0.54.Final-linux-aarch_64-fedora.jar after unzipping has META-INF/native/libnetty_tcnative_linux_aarch_64.so
  • I moved from gcr.io/distroless/java17:nonroot to openjdk:17-slim
#
# MockServer Dockerfile
#
# https://github.com/mock-server/mockserver
# https://www.mock-server.com
#

ARG source=download

# build image
FROM alpine as download

# download jar
RUN apk add --update openssl ca-certificates bash wget
# REPOSITORY is releases or snapshots
ARG REPOSITORY=releases
# VERSION is LATEST or RELEASE or x.x.x
ARG VERSION=RELEASE
# see: https://oss.sonatype.org/nexus-restlet1x-plugin/default/docs/path__artifact_maven_redirect.html
ARG REPOSITORY_URL=https://oss.sonatype.org/service/local/artifact/maven/redirect?r=${REPOSITORY}&g=org.mock-server&a=mockserver-netty&c=jar-with-dependencies&e=jar&v=${VERSION}
RUN wget --max-redirect=10 -O mockserver-netty-jar-with-dependencies.jar "$REPOSITORY_URL"
# add netty-tcnative-boringssl so file
RUN if [ "$(uname -m)" = "x86_64" ]; \
    then wget --max-redirect=10 -O netty-tcnative-boringssl-static.jar "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=releases&g=io.netty&a=netty-tcnative-boringssl-static&c=linux-x86_64&e=jar&v=2.0.54.Final"; \
    else wget --max-redirect=10 -O netty-tcnative-boringssl-static.jar "https://repo1.maven.org/maven2/io/netty/netty-tcnative/2.0.54.Final/netty-tcnative-2.0.54.Final-linux-aarch_64-fedora.jar"; \
    fi
RUN unzip netty-tcnative-boringssl-static.jar

# build image
FROM alpine as copy

# copy jar
COPY mockserver-netty-jar-with-dependencies.jar .
# add netty-tcnative-boringssl so file
RUN apk add --update openssl ca-certificates bash wget
RUN if [ "$(uname -m)" = "x86_64" ]; \
    then wget --max-redirect=10 -O netty-tcnative-boringssl-static.jar "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=releases&g=io.netty&a=netty-tcnative-boringssl-static&c=linux-x86_64&e=jar&v=2.0.54.Final"; \
    else wget --max-redirect=10 -O netty-tcnative-boringssl-static.jar "https://repo1.maven.org/maven2/io/netty/netty-tcnative/2.0.54.Final/netty-tcnative-2.0.54.Final-linux-aarch_64-fedora.jar"; \
    fi
RUN unzip netty-tcnative-boringssl-static.jar

FROM ${source} as intermediate

FROM openjdk:17-slim

# maintainer details
LABEL maintainer="James Bloom <[email protected]>"

# expose ports.
EXPOSE 1080

# copy in jar
COPY --from=intermediate mockserver-netty-jar-with-dependencies.jar /
COPY --from=intermediate META-INF/native/libnetty_tcnative_linux_*.so /usr/lib/

# don't run MockServer as root
RUN useradd -ms /bin/bash nonroot
USER nonroot

ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-cp", "/mockserver-netty-jar-with-dependencies.jar:/libs/*", "-Dmockserver.propertyFile=/config/mockserver.properties", "org.mockserver.cli.Main"]

ENV SERVER_PORT 1080

CMD []

bbednarek avatar Dec 13 '22 17:12 bbednarek

@bbednarek this looks interesting I'll try to incorporate these changes

jamesdbloom avatar Jan 09 '23 22:01 jamesdbloom

Great findings @bbednarek! If you want to use a distroless with arm64 you can use: gcr.io/distroless/java17-debian11:nonroot. Then you can omit RUN useradd -ms /bin/bash nonroot

Karamell avatar Jan 12 '23 13:01 Karamell

Thanks @Karamell. It works as a charm. @jamesdbloom I will raise PR to fix this issue.

bbednarek avatar Jan 17 '23 09:01 bbednarek

Just FYI our fork has working ARM images. Feel free to check them out.

AB-xdev avatar Jun 05 '24 12:06 AB-xdev