打包 OCI 镜像

该插件可以使用 Cloud Native Buildpacks (CNB) 从 jar 或 war 文件创建 OCI 镜像。可以使用 bootBuildImage 任务构建镜像。

出于安全原因,镜像构建和运行为非 root 用户。有关更多详细信息,请参阅 CNB 规范

当应用 javawar 插件时,该任务会自动创建,并且是 BootBuildImage 的实例。

Docker 守护程序

bootBuildImage 任务需要访问 Docker 守护程序。该任务将检查本地 Docker CLI 配置文件 以确定当前 上下文,并使用上下文连接信息与 Docker 守护程序通信。如果无法确定当前上下文或上下文没有连接信息,则该任务将使用默认的本地连接。这在所有支持的平台上无需配置即可与 Docker Engine 配合使用。

可以设置环境变量以配置 bootBuildImage 任务以使用备用本地或远程连接。下表显示了环境变量及其值

环境变量 描述

DOCKER_CONFIG

用于确定当前上下文的 Docker CLI 配置文件 的位置(默认为 $HOME/.docker

DOCKER_CONTEXT

用于从 Docker CLI 配置文件检索主机信息的 上下文 的名称(覆盖 DOCKER_HOST

DOCKER_HOST

包含 Docker 守护进程的主机和端口的 URL - 例如 tcp://192.168.99.100:2376

DOCKER_TLS_VERIFY

设置为 1 时启用安全 HTTPS 协议(可选)

DOCKER_CERT_PATH

HTTPS 证书和密钥文件的路径(如果 DOCKER_TLS_VERIFY=1 则需要,否则忽略)

Docker 守护进程连接信息也可以使用插件配置中的 docker 属性提供。下表总结了可用的属性

属性 描述

context

用于从 Docker CLI 配置文件 检索主机信息的 上下文 的名称

host

包含 Docker 守护进程的主机和端口的 URL - 例如 tcp://192.168.99.100:2376

tlsVerify

设置为 true 时启用安全 HTTPS 协议(可选)

certPath

HTTPS 证书和密钥文件的路径(如果 tlsVerifytrue 则需要,否则忽略)

bindHostToBuilder

true 时,host 属性的值将提供给为 CNB 构建器创建的容器(可选)

有关更多详细信息,另请参见 示例

Docker 注册表

如果 builderrunImage 属性指定的 Docker 镜像存储在需要身份验证的私有 Docker 镜像注册表中,则可以使用 docker.builderRegistry 属性提供身份验证凭据。

如果生成的 Docker 镜像要发布到 Docker 镜像注册表,则可以使用 docker.publishRegistry 属性提供身份验证凭据。

提供用于用户身份验证或身份令牌身份验证的属性。请参阅用于存储镜像的 Docker 注册表的文档,以获取有关支持的身份验证方法的更多信息。

下表总结了 docker.builderRegistrydocker.publishRegistry 的可用属性

属性 描述

username

Docker 镜像注册表用户的用户名。用户身份验证需要。

password

Docker 镜像注册表用户的密码。用户身份验证需要。

url

Docker 镜像注册表的地址。用户身份验证可选。

电子邮件

Docker 镜像仓库用户的电子邮件地址。对于用户身份验证是可选的。

令牌

Docker 镜像仓库用户的身份令牌。对于令牌身份验证是必需的。

有关更多详细信息,另请参见 示例

镜像自定义

插件调用一个 构建器 来协调镜像的生成。构建器包含多个 构建包,它们可以检查应用程序以影响生成的镜像。默认情况下,插件会选择一个构建器镜像。生成的镜像名称是从项目属性中推断出来的。

任务属性可用于配置构建器如何对项目进行操作。下表总结了可用的属性及其默认值

属性 命令行选项 描述 默认值

构建器

--builder

要使用的构建器镜像的名称。

GraalVM Native Image 插件 应用时,为 paketobuildpacks/builder-jammy-base:latestpaketobuildpacks/builder-jammy-tiny:latest

运行镜像

--runImage

要使用的运行镜像的名称。

没有默认值,表示应使用构建器元数据中指定的运行镜像。

镜像名称

--imageName

生成的镜像的镜像名称

docker.io/library/${project.name}:${project.version}

拉取策略

--pullPolicy

策略 用于确定何时从注册表拉取构建器和运行镜像。可接受的值为 ALWAYSNEVERIF_NOT_PRESENT

ALWAYS

环境

应传递给构建器的环境变量。

GraalVM Native Image 插件 应用时,为空或 ['BP_NATIVE_IMAGE': 'true']

构建包

构建器在构建镜像时应使用的构建包。只有指定的构建包将被使用,覆盖构建器中包含的默认构建包。构建包引用必须采用以下形式之一

  • 构建器中的构建包 - [urn:cnb:builder:]<buildpack ID>[@<version>]

  • 文件系统上目录中的构建包 - [file://]<path>

  • 文件系统上压缩的 tar (.tgz) 文件中的构建包 - [file://]<path>/<file name>

  • OCI 镜像中的构建包 - [docker://]<host>/<repo>[:<tag>][@<digest>]

无,表示构建器应使用其中包含的构建包。

绑定

卷绑定挂载 应在构建镜像时挂载到构建器容器。绑定将在创建构建器容器时未解析且未验证地传递给 Docker。绑定必须采用以下形式之一

  • <host source path>:<container destination path>[:<options>]

  • <host volume name>:<container destination path>[:<options>]

其中 <options> 可以包含

  • ro 在容器中以只读方式挂载卷

  • rw 在容器中以可读写方式挂载卷

  • volume-opt=key=value 指定由选项名称及其值组成的键值对

网络

--network

构建器容器将配置为使用的 网络驱动程序。提供的 value 将在创建构建器容器时未经验证地传递给 Docker。

清除缓存

--cleanCache

是否在构建之前清除缓存。

false

详细日志记录

启用构建器操作的详细日志记录。

false

发布

--publishImage

是否将生成的镜像发布到 Docker 仓库。

false

标签

要应用于生成的镜像的一个或多个附加标签的列表。提供给 tags 选项的值应为 **完整** 镜像引用。有关更多详细信息,请参见 标签部分

构建工作区

构建器和构建包将在镜像构建期间使用此临时工作区来存储文件。该值可以是命名卷或绑定挂载位置。

Docker 守护程序中的命名卷,其名称源自镜像名称。

构建缓存

包含构建包创建的层并用于镜像构建过程的缓存。该值可以是命名卷或绑定挂载位置。

Docker 守护程序中的命名卷,其名称源自镜像名称。

启动缓存

包含构建包创建的层并用于镜像启动过程的缓存。该值可以是命名卷或绑定挂载位置。

Docker 守护程序中的命名卷,其名称源自镜像名称。

创建时间

--createdDate

将用于设置生成的镜像元数据中 Created 字段的日期。该值必须是 ISO 8601 瞬时格式的字符串,或 now 以使用当前日期和时间。

一个固定日期,它使 构建可重复

应用程序目录

--applicationDirectory

应用程序内容将上载到构建器镜像中的目录的路径。应用程序内容也将位于生成的镜像中的此位置。

/workspace

securityOptions

--securityOptions

将应用于构建器容器的安全选项,以字符串值数组的形式提供

在 Linux 和 macOS 上为["label=disable"],在 Windows 上为[]

该插件使用 JavaPlugin 的targetCompatibility属性检测项目的目标 Java 兼容性。当使用默认的 Paketo 构建器和构建包时,该插件会指示构建包安装相同的 Java 版本。您可以按照构建器配置示例中所示覆盖此行为。

标签格式

提供给tags选项的值应为完整的镜像引用。接受的格式为[domainHost:port/][path/]name[:tag][@digest]

如果缺少域,则默认为docker.io。如果缺少路径,则默认为library。如果缺少标签,则默认为latest

一些示例

  • my-image将导致镜像引用docker.io/library/my-image:latest

  • my-repository/my-image将导致docker.io/my-repository/my-image:latest

  • example.com/my-repository/my-image:1.0.0将按原样使用

示例

自定义镜像构建器和运行镜像

如果您需要自定义用于创建镜像的构建器或用于启动已构建镜像的运行镜像,请按照以下示例所示配置任务

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	builder = "mine/java-cnb-builder"
	runImage = "mine/java-cnb-run"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	builder.set("mine/java-cnb-builder")
	runImage.set("mine/java-cnb-run")
}

此配置将使用名称为mine/java-cnb-builder且标签为latest的构建器镜像,以及名称为mine/java-cnb-run且标签为latest的运行镜像。

构建器和运行镜像也可以在命令行上指定,如以下示例所示

$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run

构建器配置

如果构建器公开配置选项,则可以使用environment属性设置这些选项。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	environment["BP_JVM_VERSION"] = "17"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	environment.set(environment.get() + mapOf("BP_JVM_VERSION" to "17"))
}

如果 Docker 守护程序运行的构建器与构建包下载工件的网络位置之间存在网络代理,则需要配置构建器以使用代理。当使用 Paketo 构建器时,可以通过设置HTTPS_PROXY和/或HTTP_PROXY环境变量来实现,如以下示例所示

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	environment["HTTP_PROXY"] = "http://proxy.example.com"
	environment["HTTPS_PROXY"] = "https://proxy.example.com"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	environment.set(mapOf("HTTP_PROXY" to "http://proxy.example.com",
						"HTTPS_PROXY" to "https://proxy.example.com"))
}

运行时 JVM 配置

Paketo Java 构建包通过设置 `JAVA_TOOL_OPTIONS` 环境变量来 配置 JVM 运行时环境。构建包提供的 `JAVA_TOOL_OPTIONS` 值可以在应用程序镜像在容器中启动时修改,以自定义 JVM 运行时行为。

应该存储在镜像中并应用于每次部署的环境变量修改,可以按照 Paketo 文档 中的描述进行设置,如下例所示

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	environment["BPE_DELIM_JAVA_TOOL_OPTIONS"] = " "
	environment["BPE_APPEND_JAVA_TOOL_OPTIONS"] = "-XX:+HeapDumpOnOutOfMemoryError"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	environment.set(mapOf(
		"BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
		"BPE_APPEND_JAVA_TOOL_OPTIONS" to "-XX:+HeapDumpOnOutOfMemoryError"
	))
}

自定义镜像名称

默认情况下,镜像名称是从项目的 `name` 和 `version` 推断出来的,类似于 `docker.io/library/${project.name}:${project.version}`。您可以通过设置任务属性来控制名称,如下例所示

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	imageName = "example.com/library/${project.name}"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	imageName.set("example.com/library/${project.name}")
}

请注意,此配置没有提供显式标签,因此使用 `latest`。也可以指定标签,可以使用 `${project.version}`、构建中可用的任何属性或硬编码版本。

镜像名称也可以在命令行中指定,如下例所示

$ gradle bootBuildImage --imageName=example.com/library/my-app:v1

构建包

默认情况下,构建器将使用构建器镜像中包含的构建包,并按照预定义的顺序应用它们。可以提供一组备用构建包来应用构建器中未包含的构建包,或更改包含的构建包的顺序。当提供一个或多个构建包时,将只应用指定的构建包。

以下示例指示构建器使用打包在 `tgz` 文件中的自定义构建包,然后使用构建器中包含的构建包。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	buildpacks = ["file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"]
}
tasks.named<BootBuildImage>("bootBuildImage") {
	buildpacks.set(listOf("file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"))
}

构建包可以在以下任何形式中指定。

位于 CNB 构建器中的构建包(如果构建器中只有一个与 `buildpack-id` 匹配的构建包,则可以省略版本)

指向包含构建包内容的目录的路径(在 Windows 上不支持)

  • file:///path/to/buildpack/

  • /path/to/buildpack/

指向包含构建包内容的压缩 tar 文件的路径

  • file:///path/to/buildpack.tgz

  • /path/to/buildpack.tgz

包含已打包的构建包的 OCI 镜像

  • docker://example/buildpack

  • docker:///example/buildpack:latest

  • docker:///example/buildpack@sha256:45b23dee08…​

  • example/buildpack

  • example/buildpack:latest

  • example/buildpack@sha256:45b23dee08…​

镜像发布

通过启用 publish 选项,可以将生成的镜像发布到 Docker 仓库。

如果 Docker 仓库需要身份验证,可以使用 docker.publishRegistry 属性配置凭据。如果 Docker 仓库不需要身份验证,则可以省略 docker.publishRegistry 配置。

将要发布镜像的仓库由镜像名称的仓库部分确定(在这些示例中为 docker.example.com)。如果配置了 docker.publishRegistry 凭据并且包含 url 属性,则此值将传递给仓库,但不用于确定发布仓库位置。
  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	imageName.set("docker.example.com/library/${project.name}")
	publish = true
	docker {
		publishRegistry {
			username = "user"
			password = "secret"
		}
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	imageName.set("docker.example.com/library/${project.name}")
	publish.set(true)
	docker {
		publishRegistry {
			username.set("user")
			password.set("secret")
		}
	}
}

发布选项也可以在命令行中指定,如以下示例所示

$ gradle bootBuildImage --imageName=docker.example.com/library/my-app:v1 --publishImage

构建器缓存和工作区配置

CNB 构建器会缓存构建和启动镜像时使用的层。默认情况下,这些缓存存储在 Docker 守护程序中的命名卷中,命名卷的名称源自目标镜像的完整名称。如果镜像名称经常更改,例如当项目版本用作镜像名称中的标签时,则缓存可能会经常失效。

可以配置缓存卷以使用备用名称,以便更好地控制缓存生命周期,如以下示例所示

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	buildCache {
		volume {
			name = "cache-${rootProject.name}.build"
		}
	}
	launchCache {
		volume {
			name = "cache-${rootProject.name}.launch"
		}
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	buildCache {
		volume {
			name.set("cache-${rootProject.name}.build")
		}
	}
	launchCache {
		volume {
			name.set("cache-${rootProject.name}.launch")
		}
	}
}

构建器和构建包需要一个位置来存储镜像构建期间的临时文件。默认情况下,此临时构建工作区存储在命名卷中。

可以配置缓存和构建工作区以使用绑定挂载而不是命名卷,如以下示例所示

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	buildWorkspace {
		bind {
			source = "/tmp/cache-${rootProject.name}.work"
		}
	}
	buildCache {
		bind {
			source = "/tmp/cache-${rootProject.name}.build"
		}
	}
	launchCache {
		bind {
			source = "/tmp/cache-${rootProject.name}.launch"
		}
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	buildWorkspace {
		bind {
			source.set("/tmp/cache-${rootProject.name}.work")
		}
	}
	buildCache {
		bind {
			source.set("/tmp/cache-${rootProject.name}.build")
		}
	}
	launchCache {
		bind {
			source.set("/tmp/cache-${rootProject.name}.launch")
		}
	}
}

Docker 配置

minikube 的 Docker 配置

插件可以与minikube 提供的 Docker 守护程序通信,而不是默认的本地连接。

在 Linux 和 macOS 上,可以在 minikube 启动后使用命令 eval $(minikube docker-env) 设置环境变量。

还可以配置插件以使用 minikube 守护程序,方法是提供类似于以下示例中所示的连接详细信息

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	docker {
		host = "tcp://192.168.99.100:2376"
		tlsVerify = true
		certPath = "/home/user/.minikube/certs"
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	docker {
		host.set("tcp://192.168.99.100:2376")
		tlsVerify.set(true)
		certPath.set("/home/user/.minikube/certs")
	}
}

podman 的 Docker 配置

该插件可以与 podman 容器引擎 通信。

可以通过提供类似于以下示例中所示的连接详细信息,将插件配置为使用 podman 本地连接。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	docker {
		host = "unix:///run/user/1000/podman/podman.sock"
		bindHostToBuilder = true
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	docker {
		host.set("unix:///run/user/1000/podman/podman.sock")
		bindHostToBuilder.set(true)
	}
}
安装了 podman CLI 后,可以使用命令 podman info --format='{{.Host.RemoteSocket.Path}}' 获取此示例中显示的 docker.host 配置属性的值。

Colima 的 Docker 配置

该插件可以与 Colima 提供的 Docker 守护进程通信。可以使用命令 export DOCKER_HOST=$(docker context inspect colima -f '{{.Endpoints.docker.Host}}'). 设置 DOCKER_HOST 环境变量。

该插件也可以配置为使用 Colima 守护进程,方法是提供类似于以下示例中所示的连接详细信息。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	docker {
		host = "unix://${System.properties['user.home']}/.colima/docker.sock"
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	docker {
		host.set("unix://${System.getProperty("user.home")}/.colima/docker.sock")
	}
}

Docker 身份验证配置

如果构建器或运行映像存储在支持用户身份验证的私有 Docker 仓库中,则可以使用 docker.builderRegistry 属性提供身份验证详细信息,如以下示例所示。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	docker {
		builderRegistry {
			username = "user"
			password = "secret"
			url = "https://docker.example.com/v1/"
			email = "[email protected]"
		}
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	docker {
		builderRegistry {
			username.set("user")
			password.set("secret")
			url.set("https://docker.example.com/v1/")
			email.set("[email protected]")
		}
	}
}

如果构建器或运行映像存储在支持令牌身份验证的私有 Docker 仓库中,则可以使用 docker.builderRegistry 提供令牌值,如以下示例所示。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	docker {
		builderRegistry {
			token = "9cbaf023786cd7..."
		}
	}
}
tasks.named<BootBuildImage>("bootBuildImage") {
	docker {
		builderRegistry {
			token.set("9cbaf023786cd7...")
		}
	}
}