首页 > 解决方案 > 使用心轴创建 Quarkus Docker 容器失败

问题描述

我想创建一个基于 mandrel-image 的 docker 容器并遵循本指南:https ://quarkus.io/guides/building-native-image#multistage-docker

但是,无论是多阶段还是仅仅修改 Dockerfile.native 以使用它工作的心轴图像。如果我使用作为入门项目一部分的 Dockerfile.native 并仅根据 FROM 子句和要使用的基本映像对其进行修改

FROM quay.io/quarkus/ubi-quarkus-mandrel:21.2.0.1-Final-java11 AS build
WORKDIR /work/
RUN chown 1001 /work \
    && chmod "g+rwX" /work \
    && chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application

EXPOSE 8080
USER 1001

CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

我将收到以下构建错误:

 => ERROR [3/4] RUN chown 1001 /work     && chmod "g+rwX" /work     && chown 1001:root /work                       1.0s
------
 > [3/4] RUN chown 1001 /work     && chmod "g+rwX" /work     && chown 1001:root /work:
#6 0.915 chown: changing ownership of '/work': Operation not permitted
------
executor failed running [/bin/sh -c chown 1001 /work     && chmod "g+rwX" /work     && chown 1001:root /work]: exit code: 1

另一方面,如果我使用网站上显示的 dockerfile 并替换 FROM 子句

FROM quay.io/quarkus/ubi-quarkus-mandrel:21.2.0.1-Final-java11
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

构建完成,但是当我尝试运行它时,出现以下错误

[./application:51]    classlist:   4,403.97 ms,  0.96 GB
Error: Main entry point class './application' not found.
Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
[./application:51]      [total]:   4,467.02 ms,  0.96 GB
Error: Image build request failed with exit status 1

我在这里想念什么?您知道如何使用 quarkus 运行基于心轴的本机容器吗?

非常感谢!

标签: dockerquarkus

解决方案


Quarkus 原生可执行文件有两种镜像。

  • Builder 映像- 包含 Mandrel 发行版、JDK、C 编译器、库和所有必要工具的映像。
  • 运行时映像- 一个准系统映像,仅包含最终的 Quarkus 本机可执行文件、C 运行时和必要的运行时库(例如 zlib)。

因此,您可以使用 Quarkus 拉取和控制的Builder 映像将您的应用程序构建为本机可执行文件,例如

./mvnw clean package -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:21.3-java11

...然后您可以使用这样的 Dockerfile 将生成的二进制可执行文件填充到该运行时映像中:

FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
WORKDIR /work/
RUN chown 1001 /work \
    && chmod "g+rwX" /work \
    && chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application

EXPOSE 8080
USER 1001

CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

如果您不希望 Quarkus 为您控制该Builder 映像并且您希望拥有自己的多阶段构建,您也可以这样做。

例如,使用此示例 Quarkus 应用程序:

curl -O -J  https://code.quarkus.io/d?e=io.quarkus:quarkus-resteasy
unzip code-with-quarkus.zip 
cd code-with-quarkus/
rm .dockerignore
vim Dockerfile

Dockerfile:

FROM quay.io/quarkus/ubi-quarkus-mandrel:21.3-java11 as nativebuilder
WORKDIR /work/
USER root
COPY src /work/src
COPY .mvn /work/.mvn
COPY mvnw pom.xml /work/
RUN ./mvnw clean package -Pnative

FROM registry.access.redhat.com/ubi8/ubi-micro:8.4
COPY --from=nativebuilder \
   /lib64/libz.so.1 \
   /lib64/libstdc++.so.6 \
   /lib64/libgcc_s.so.1 \
   /lib64/libbz2.so.1 \
   /lib64/libm.so.6 \
   /lib64/libbz2.so.1 \
   /lib64/libexpat.so.1 \
   /lib64/libuuid.so.1 \
   /lib64/
USER 1001
WORKDIR /work/
COPY --chown=1001:root --from=nativebuilder /work/target/*-runner /work/application
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

接着

docker build -f ./Dockerfile -t my-quarkus-test .  
docker run -i  -p 8080:8080 my-quarkus-test:latest

您绝对应该使用缓存 maven 阶段,例如使用,dependency:go-offline这样您就不必每次都在 nativebuilder 中下载整个 Internet。

最后但并非最不重要的一点是,如果您使用ubi-minimal而不是ubi-micro您可以省略复制这些/so文件,代价是磁盘上的图像大小稍大。但它不会影响您的运行时应用程序内存占用。

让我知道它是否有帮助,我非常感谢反馈。


推荐阅读