Container Images

Quarkus 提供了用于构建(和发布)容器映像的扩展。目前,它支持:

Quarkus provides extensions for building (and pushing) container images. Currently, it supports:

Container Image extensions

Jib

扩展 `quarkus-container-image-jib`由 Jib提供支持,用于执行容器映像构建。将 Jib 用于 Quarkus 的主要好处在于,所有依赖项(`target/lib`下找到的所有内容)都缓存在与实际应用程序不同的层中,从而使重建变得非常快速且占用空间较小(在发布时)。使用此扩展的另一个重要好处在于,它提供了创建容器映像而无需任何专用客户端工具(如 Docker)或运行守护程序进程(如 Docker 守护程序)的能力,而只需要将内容发布到容器映像注册表的能力。

The extension quarkus-container-image-jib is powered by Jib for performing container image builds. The major benefit of using Jib with Quarkus is that all the dependencies (everything found under target/lib) are cached in a different layer than the actual application making rebuilds really fast and small (when it comes to pushing). Another important benefit of using this extension is that it provides the ability to create a container image without having to have any dedicated client side tooling (like Docker) or running daemon processes (like the Docker daemon) when all that is needed is the ability to push to a container image registry.

要使用此功能,请将以下扩展名添加到您的项目:

To use this feature, add the following extension to your project:

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

在仅需要构建容器映像并且不需要发布到注册表的情况下(基本上通过设置 quarkus.container-image.build=true`并使 `quarkus.container-image.push`保持未设置状态——它默认为 `false),此扩展将创建一个容器映像并将其注册到 Docker 守护程序。这意味着尽管不用 Docker 构建映像,但它仍然是必需的。另外请注意,使用此模式时,在执行 `docker images`时,构建的容器映像 *will*将显示出来。

In situations where all that is needed to build a container image and no push to a registry is necessary (essentially by having set quarkus.container-image.build=true and left quarkus.container-image.push unset - it defaults to false), then this extension creates a container image and registers it with the Docker daemon. This means that although Docker isn’t used to build the image, it is nevertheless necessary. Also note that using this mode, the built container image will show up when executing docker images.

Including extra files

在某些情况下,需要将除 Quarkus 构建生成的之外的其他文件添加到容器映像中。为了支持这种情况,Quarkus 会将 src/main/jib`下的所有文件复制到构建的容器映像中(本质上与 Jib Maven 和 Gradle 插件支持的理念相同)。例如,如果存在 `src/main/jib/foo/bar,则 `/foo/bar`将被添加到容器文件系统中。

There are cases when additional files (other than ones produced by the Quarkus build) need to be added to a container image. To support these cases, Quarkus copies any file under src/main/jib into the built container image (which is essentially the same idea that the Jib Maven and Gradle plugins support). For example, the presence of src/main/jib/foo/bar would result in /foo/bar being added into the container filesystem.

JVM Debugging

在某些情况下,可能需要在运行时有条件地启用构建的容器映像的 Java 调试。

There are cases where the built container image may need to have Java debugging conditionally enabled at runtime.

当基础映像未更改时(因此使用了 ubi8/openjdk-11-runtimeubi8/openjdk-17-runtime`或 `ubi8/openjdk-21-runtime),则可以在启动时使 JVM 在调试端口上进行侦听,为此可使用 `quarkus.jib.jvm-additional-arguments`配置属性。

When the base image has not been changed (and therefore ubi8/openjdk-11-runtime, ubi8/openjdk-17-runtime, or ubi8/openjdk-21-runtime is used), then the quarkus.jib.jvm-additional-arguments configuration property can be used in order to make the JVM listen on the debug port at startup.

确切的配置为:

The exact configuration is:

quarkus.jib.jvm-additional-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005

其他基础映像可能提供在设置环境变量时启用调试的启动脚本,在这种情况下,你将在启动容器时设置该环境变量。

Other base images might provide launch scripts that enable debugging when an environment variable is set, in which case you would set than environment variable when launching the container.

Custom Entrypoint

可以使用 `quarkus.jib.jvm-entrypoint`配置属性完全覆盖容器入口点,因此可以使用它对 JVM 调试配置进行硬编码或指向处理详细信息的脚本。

The quarkus.jib.jvm-entrypoint configuration property can be used to completely override the container entry point and can thus be used to either hard code the JVM debug configuration or point to a script that handles the details.

例如,如果使用基础映像 ubi8/openjdk-11-runtime、`ubi8/openjdk-17-runtime`or `ubi8/openjdk-21-runtime`构建容器,则可以在应用程序配置文件中对入口点进行硬编码。

For example, if the base images ubi8/openjdk-11-runtime, ubi8/openjdk-17-runtime or ubi8/openjdk-21-runtime are used to build the container, the entry point can be hard-coded on the application properties file.

Example application.properties
quarkus.jib.jvm-entrypoint=java,-Dcustom.param=custom_value,-jar,quarkus-run.jar

或者,可以创建自定义启动脚本并在配置文件中引用它。如果需要使用环境变量设置应用程序参数,此方法会更好:

Or a custom start-up script can be created and referenced on the properties file. This approach works better if there’s a need to set application params using environment variables:

Example application.properties
quarkus.jib.jvm-entrypoint=/bin/sh,run-java.sh
Example src/main/jib/home/jboss/run-java.sh
java \
  -Djavax.net.ssl.trustStore=/deployments/truststore \
  -Djavax.net.ssl.trustStorePassword="$TRUST_STORE_PASSWORD" \
  -jar quarkus-run.jar

/home/jboss`是基础映像 `ubi8/openjdk-11-runtimeubi8/openjdk-17-runtime`和 `ubi8/openjdk-21-runtime (Dockerfile for ubi8/openjdk-17-runtime) 中所有 quarkus 二进制文件的工作目录

/home/jboss is the WORKDIR for all quarkus binaries in the base images ubi8/openjdk-11-runtime, ubi8/openjdk-17-runtime and ubi8/openjdk-21-runtime (Dockerfile for ubi8/openjdk-17-runtime)

Multi-module projects and layering

在构建一个包含一个 Quarkus 应用程序(作为其中一个模块)的多模块项目和各种支持项目依赖项(作为其他模块)时,Quarkus 支持将这些支持模块放在与应用程序其他依赖项分开的容器映像层中,且预期这些支持模块将比常规的应用程序依赖项更频繁地发生更改——因此,如果应用程序依赖项未更改,将可以更快地进行重建。

When building a multi-module project containing a Quarkus application as one module and various supporting project dependencies as other modules, Quarkus supports placing these supporting modules in a separate container image layer from the rest of the application dependencies, with the expectation that these supporting modules will change more frequently than the regular application dependencies - thus making a rebuild faster if the application dependencies have not changed.

为了启用此特性,需要将属性 quarkus.bootstrap.workspace-discovery`设置为 `true,方法是将其作为在调用构建工具时传入的系统属性,或作为构建工具属性。在 `application.properties`设置此属性会 *not*生效,因为需要在构建过程的非常早的阶段了解此属性。

To enable this feature, the property quarkus.bootstrap.workspace-discovery needs to be set to true either as a system property when invoking the build tool, either as a build tool property. Setting this property in application.properties will not work because this property needs to be known very early on in the build process.

AppCDS

在使用 Jib 生成容器镜像时,Quarkus 支持生成并包含 Application Class Data Sharing 存档。有关更多详细信息,请参见 AppCDS documentation

Quarkus supports generating and including an Application Class Data Sharing archive when generating a container image using Jib. See the AppCDS documentation for more details.

Docker

扩展 quarkus-container-image-docker 使用 src/main/docker 中的 Docker 二进制文件和生成的 Dockerfile 来执行 Docker 构建。

The extension quarkus-container-image-docker is using the Docker binary and the generated Dockerfiles under src/main/docker in order to perform Docker builds.

要使用此功能,请向项目添加以下扩展。

To use this feature, add the following extension to your project.

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

quarkus-container-image-docker 扩展能够使用 docker buildx buildcreating multi-platform (or multi-arch) 镜像。请参见下面 Docker Options 部分中的 quarkus.docker.buildx.* 配置项。

The quarkus-container-image-docker extension is capable of creating multi-platform (or multi-arch) images using docker buildx build. See the quarkus.docker.buildx.* configuration items in the DockerOptions section below.

docker buildx build 仅在为单个平台构建时支持 loading the result of a builddocker images。所以,如果您在 quarkus.docker.buildx.platform 属性中指定多个参数,结果镜像将不会加载到 docker images。如果省略 quarkus.docker.buildx.platform 或只指定单个平台,它将被加载到 docker images

docker buildx build ONLY supports loading the result of a build to docker images when building for a single platform. Therefore, if you specify more than one argument in the quarkus.docker.buildx.platform property, the resulting images will not be loaded into docker images. If quarkus.docker.buildx.platform is omitted or if only a single platform is specified, it will then be loaded into docker images.

这意味着,如果您想一次为多个平台构建镜像(即 quarkus.docker.buildx.platform=linux/amd64,linux/arm64),则需要将镜像直接作为构建流程的一部分(quarkus.container-image.push=true)推送。构建多平台镜像时,Docker buildx 不支持加载到本地注册表中。

This means that if you want to build images for more than one platform at a time (i.e. quarkus.docker.buildx.platform=linux/amd64,linux/arm64), you need to push the images (quarkus.container-image.push=true) directly as part of the build process. Docker buildx does not support loading into the local registry when building multi-platform images.

Podman

扩展 quarkus-container-image-podman 使用 Podmansrc/main/docker 中生成的 Dockerfiles 来执行容器构建。

The extension quarkus-container-image-podman uses Podman and the generated Dockerfiles under src/main/docker in order to perform container builds.

要使用此功能,请向项目添加以下扩展。

To use this feature, add the following extension to your project.

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

When to use Docker vs Podman extension

Docker extension 始终都与 Podman 向后兼容,因为 Podman 暴露了一个 Docker-compatible API。您可以使用 Docker 扩展来用 Podman 构建容器镜像(请参见 Using Podman with Quarkus guide)。

The docker is and has always been backwards-compatible with Podman because Podman exposes a Docker-compatible API. You can build container images with Podman using the Docker extension (see the Using Podman with Quarkus guide).

在分别执行 Docker 或 Podman 特有的操作时,请分别使用 quarkus-container-image-dockerquarkus-container-image-podman 扩展。

Use either the quarkus-container-image-docker or quarkus-container-image-podman extension when doing things specific to either Docker or Podman, respectively.

例如,Docker 和 Podman 的多平台镜像构建实现不同。Docker 使用 the buildx plugin,而 Podman 可以 natively 构建多平台镜像。由于这个原因,您需要使用特定的扩展来执行此功能。

For example, building multi-platform images is implemented differently for Docker and Podman. Docker uses the buildx plugin whereas Podman can build multi-platform images natively. Because of this, you would need to use the specific extension to perform that function.

OpenShift

扩展 quarkus-container-image-openshift 使用 OpenShift 二进制版本构建,以便在 OpenShift 集群内执行容器构建。二进制版本构建的想法是,您只需将伪像和它的依赖项上传到集群,在构建期间它们将被合并到构建器镜像(默认为 fabric8/s2i-java)。

The extension quarkus-container-image-openshift is using OpenShift binary builds in order to perform container builds inside the OpenShift cluster. The idea behind the binary build is that you just upload the artifact and its dependencies to the cluster and during the build they will be merged to a builder image (defaults to fabric8/s2i-java).

这种方法的好处在于,它可以与 OpenShift 的 DeploymentConfig 结合使用,后者使得向集群推出变更变得更加容易。

The benefit of this approach, is that it can be combined with OpenShift’s DeploymentConfig that makes it easy to roll out changes to the cluster.

要使用此功能,请向项目添加以下扩展。

To use this feature, add the following extension to your project.

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

OpenShift 构建要求创建 BuildConfig 和两个 ImageStream 资源,一个用于构建器镜像,一个用于输出镜像。Quarkus Kubernetes 扩展负责创建此类对象。

OpenShift builds require creating a BuildConfig and two ImageStream resources, one for the builder image and one for the output image. The creation of such objects is being taken care of by the Quarkus Kubernetes extension.

Buildpack

扩展 quarkus-container-image-buildpack 使用构建包来执行容器镜像构建。本质上,构建包会使用 Docker 守护程序来执行实际构建。虽然构建包支持 Docker 的替代品,但此扩展只支持 Docker。

The extension quarkus-container-image-buildpack is using buildpacks in order to perform container image builds. Under the hood buildpacks will use a Docker daemon for the actual build. While buildpacks support alternatives to Docker, this extension will only work with Docker.

此外,用户将必须配置要使用的构建镜像(未提供默认镜像)。例如:

Additionally, the user will have to configure which build image to use (no default image is provided). For example:

quarkus.buildpack.jvm-builder-image=<jvm builder image>

或者对于本机:

or for native:

quarkus.buildpack.native-builder-image=<native builder image>

要使用此功能,请向项目添加以下扩展。

To use this feature, add the following extension to your project.

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

使用构建包容器镜像扩展时,强烈建议在属性配置中避免添加 quarkus.container-image.build=true,因为它可能触发构建中的嵌套构建。最好将其作为选项传递给构建命令。

When using the buildpack container image extension it is strongly advised to avoid adding quarkus.container-image.build=true in your properties configuration as it might trigger nesting builds within builds. It’s preferable to pass it as an option to the build command instead.

Building

要为你的项目构建一个容器镜像,请使用 Quarkus 支持的任何方法设置 quarkus.container-image.build=true

To build a container image for your project, quarkus.container-image.build=true needs to be set using any of the ways that Quarkus supports.

include::{includes}/devtools/build.adoc[]:!build-additional-parameters:

Unresolved directive in container-image.adoc - include::{includes}/devtools/build.adoc[] :!build-additional-parameters:

如果你想要构建本机容器镜像,并且已经有现有本机镜像,则可以设置 -Dquarkus.native.reuse-existing=true,这样本机镜像构建将不会重新运行。

If you ever want to build a native container image and already have an existing native image you can set -Dquarkus.native.reuse-existing=true and the native image build will not be re-run.

Using @QuarkusIntegrationTest

要对生成的镜像运行测试,请使用 Quarkus 支持的任何方法设置 quarkus.container-image.build=true

To run tests on the resulting image, quarkus.container-image.build=true needs to be set using any of the ways that Quarkus supports.

Maven
./mvnw verify -Dquarkus.container-image.build=true
Gradle
./gradlew quarkusIntTest -Dquarkus.container-image.build=true

Pushing

要推送项目的容器镜像,请使用 Quarkus 支持的任何方法设置 quarkus.container-image.push=true

To push a container image for your project, quarkus.container-image.push=true needs to be set using any of the ways that Quarkus supports.

include::{includes}/devtools/build.adoc[]:!build-additional-parameters:

Unresolved directive in container-image.adoc - include::{includes}/devtools/build.adoc[] :!build-additional-parameters:

如果未设置注册中心(使用 quarkus.container-image.registry),那么将使用 `docker.io`作为默认值。

If no registry is set (using quarkus.container-image.registry) then docker.io will be used as the default.

Selecting among multiple extensions

同时使用多个扩展作为同一构建的组成部分是没有意义的。当出现多个容器镜像扩展时,将引发一个错误来告知用户。用户可以移除不必要的扩展,也可以使用 `application.properties`选择一个扩展。

It does not make sense to use multiple extension as part of the same build. When multiple container image extensions are present, an error will be raised to inform the user. The user can either remove the unneeded extensions or select one using application.properties.

例如,如果 container-image-dockercontainer-image-podman`同时存在,用户需要使用 `container-image-docker

For example, if both container-image-docker and container-image-podman are present and the user needs to use container-image-docker:

quarkus.container-image.builder=docker

Integrating with systemd-notify

要通过 Podman 和 Systemd 以 Linux 服务的形式部署 Quarkus 应用,如果正在构建容器镜像,则可能需要考虑将 Quarkus Systemd Notify Extension包含在你的应用中,方法如下:

If you are building a container image in order to deploy your Quarkus application as a Linux service with Podman and Systemd, you might want to consider including the Quarkus Systemd Notify Extension as part of your application, with:

Unresolved directive in container-image.adoc - include::{includes}/devtools/extension-add.adoc[]

Customizing

以下属性可用于自定义容器镜像构建流程。

The following properties can be used to customize the container image build process.

Container Image Options

Unresolved directive in container-image.adoc - include::{generated-dir}/config/quarkus-container-image.adoc[]

Using CI Environments

各种 CI 环境提供了开箱即用的容器镜像注册中心,可以将其与容器镜像 Quarkus 扩展结合使用,以便轻松创建和推送 Quarkus 应用到该注册中心。

Various CI environments provide a ready to use container-image registry which can be combined with the container-image Quarkus extensions in order to effortlessly create and push a Quarkus application to said registry.

例如, GitLab 提供了这样的注册中心,并且在提供的 CI 环境中,CI_REGISTRY_IMAGE 环境变量可用(请参阅 GitLab 的 documentation 了解更多信息),可以在 Quarkus 中像这样使用:

For example, GitLab provides such a registry and in the provided CI environment, makes available the CI_REGISTRY_IMAGE environment variable (see GitLab’s documentation) for more information), which can be used in Quarkus like so:

quarkus.container-image.image=${CI_REGISTRY_IMAGE}

有关如何将属性与环境变量结合使用的更多信息,请参阅 this

See this for more information on how to combine properties with environment variables.

Jib Options

除了通用的容器镜像选项外,container-image-jib 还提供了以下选项:

In addition to the generic container image options, the container-image-jib also provides the following options:

Unresolved directive in container-image.adoc - include::{generated-dir}/config/quarkus-container-image-jib.adoc[]

Docker Options

除了通用的容器镜像选项外,container-image-docker 还提供了以下选项:

In addition to the generic container image options, the container-image-docker also provides the following options:

Unresolved directive in container-image.adoc - include::{generated-dir}/config/quarkus-container-image-docker.adoc[]

Podman Options

除了通用的容器镜像选项外,container-image-podman 还提供了以下选项:

In addition to the generic container image options, the container-image-podman also provides the following options:

Unresolved directive in container-image.adoc - include::{generated-dir}/config/quarkus-container-image-podman.adoc[]

OpenShift Options

除了通用的容器镜像选项外,container-image-openshift 还提供了以下选项:

In addition to the generic container image options, the container-image-openshift also provides the following options:

Unresolved directive in container-image.adoc - include::{generated-dir}/config/quarkus-container-image-openshift_quarkus.openshift.adoc[]