打包 OCI 镜像

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

出于安全原因,镜像构建和运行都使用非 root 用户。更多详情请参阅 CNB 规范

当应用了 javawar 插件时,会自动创建此任务,并且它是 BootBuildImage 的一个实例。

Docker 守护进程

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

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

环境变量 描述

DOCKER_CONFIG

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

DOCKER_CONTEXT

用于从 Docker CLI 配置文件中检索主机信息的 context 名称 (覆盖 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 配置文件中检索主机信息的 context 名称

host

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

tlsVerify

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

certPath

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

bindHostToBuilder

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

更多详情,另请参阅 示例

Docker 注册中心

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

如果要将生成的 Docker 镜像发布到 Docker 镜像注册中心,可以使用 docker.publishRegistry 属性提供认证凭据。

提供了用于用户认证或身份令牌认证的属性。有关支持的认证方法的更多信息,请查阅用于存储镜像的 Docker 注册中心的文档。

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

属性 描述

username

Docker 镜像注册中心用户的用户名。用户认证必需。

password

Docker 镜像注册中心用户的密码。用户认证必需。

url

Docker 镜像注册中心的地址。用户认证可选。

email

Docker 镜像注册中心用户的电子邮件地址。用户认证可选。

token

Docker 镜像注册中心用户的身份令牌。令牌认证必需。

更多详情,另请参阅 示例

镜像自定义

该插件会调用一个 builder 来协调镜像的生成。builder 包含多个 buildpacks,可以检查应用以影响生成的镜像。默认情况下,插件会选择一个 builder 镜像。生成的镜像名称是根据项目属性推断的。

任务属性可以用来配置 builder 应如何操作项目。下表总结了可用的属性及其默认值。

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

builder

--builder

要使用的 builder 镜像的名称。

paketobuildpacks/builder-jammy-java-tiny:latest

trustBuilder

--trustBuilder

是否将 builder 视为信任的

如果 builder 是以下之一则为 truepaketobuildpacks/builder-jammy-java-tinypaketobuildpacks/builder-noble-java-tinypaketobuildpacks/builder-jammy-tinypaketobuildpacks/builder-jammy-basepaketobuildpacks/builder-jammy-fullpaketobuildpacks/builder-jammy-buildpackless-tinypaketobuildpacks/builder-jammy-buildpackless-basepaketobuildpacks/builder-jammy-buildpackless-fullgcr.io/buildpacks/builderheroku/builder;否则为 false

imagePlatform

--imagePlatform

拉取的任何 builder、run 和 buildpack 镜像的平台(操作系统和架构)。必须采用 OS[/architecture[/variant]] 的形式,例如 linux/amd64linux/arm64linux/arm/v5。请参考正在使用的 builder 的文档以确定可用的镜像 OS 和架构选项。

无默认值,表示应使用宿主机的平台。

runImage

--runImage

要使用的 run 镜像的名称。

无默认值,表示应使用 Builder 元数据中指定的 run 镜像。

imageName

--imageName

生成镜像的镜像名称

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

pullPolicy

--pullPolicy

用于确定何时从注册中心拉取 builder 和 run 镜像的策略。可接受的值有 ALWAYSNEVERIF_NOT_PRESENT

ALWAYS

environment

应该传递给 builder 的环境变量。

空。

buildpacks

builder 在构建镜像时应使用的 buildpacks。只会使用指定的 buildpacks,覆盖 builder 中包含的默认 buildpacks。Buildpack 引用必须采用以下形式之一:

  • builder 中的 Buildpack - [urn:cnb:builder:]<buildpack ID>[@<version>]

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

  • 文件系统上 gzipped tar (.tgz) 文件中的 Buildpack - [file://]<path>/<file name>

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

无,表示 builder 应使用其包含的 buildpacks。

bindings

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

  • <宿主机源路径>:<容器目标路径>[:<选项>]

  • <宿主机卷名称>:<容器目标路径>[:<选项>]

其中 <选项> 可以包含:

  • ro 在容器中将卷挂载为只读

  • rw 在容器中将卷挂载为可读写

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

network

--network

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

cleanCache

--cleanCache

是否在构建前清理缓存。

false

verboseLogging

启用 builder 操作的详细日志记录。

false

publish

--publishImage

是否将生成的镜像发布到 Docker 注册中心。

false

tags

应用于生成的镜像的一个或多个附加标签列表。提供给 tags 选项的值应该是完整的镜像引用。更多详情请参阅tags 部分

buildWorkspace

builder 和 buildpacks 在镜像构建期间用于存储临时文件的临时工作空间。该值可以是一个命名卷或一个绑定挂载位置。

Docker 守护进程中的一个命名卷,其名称派生自镜像名称。

buildCache

包含由 buildpacks 创建并在镜像构建过程中使用的层的缓存。该值可以是一个命名卷或一个绑定挂载位置。

Docker 守护进程中的一个命名卷,其名称派生自镜像名称。

launchCache

包含由 buildpacks 创建并在镜像启动过程中使用的层的缓存。该值可以是一个命名卷或一个绑定挂载位置。

Docker 守护进程中的一个命名卷,其名称派生自镜像名称。

createdDate

--createdDate

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

一个固定日期,用于实现构建的可重现性

applicationDirectory

--applicationDirectory

应用内容将被上传到 builder 镜像中某个目录的路径。应用内容在生成的镜像中也会在此位置。

/workspace

securityOptions

--securityOptions

将应用于 builder 容器的安全选项,作为字符串数组提供。

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

插件使用 JavaPlugin 的 targetCompatibility 属性检测项目的目标 Java 兼容性。使用默认的 Paketo builder 和 buildpacks 时,插件会指示 buildpacks 安装相同的 Java 版本。你可以覆盖此行为,如builder 配置示例所示。
默认的 builder paketobuildpacks/builder-jammy-java-tiny:latest 包含精简的系统库集,并且不包含 shell。需要 shell 来运行启动脚本的应用(例如,当应用了 application 插件 以生成分发 zip 归档时),或者依赖于不存在的系统库的应用,应该覆盖 builder 配置,使用包含 shell 和更广泛的系统库集的 builder,例如 paketobuildpacks/builder-jammy-base:latestpaketobuildpacks/builder-jammy-full:latest

Tags 格式

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

如果缺少域,则默认为 docker.io。如果缺少路径,则默认为 library。如果缺少 tag,则默认为 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 将按原样使用

示例

自定义镜像 Builder 和 Run 镜像

如果你需要自定义用于创建镜像的 builder 或用于启动已构建镜像的 run 镜像,请按以下示例配置任务:

  • 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、tag 为 latest 的 builder 镜像,以及名称为 mine/java-cnb-run、tag 为 latest 的 run 镜像。

builder 和 run 镜像也可以在命令行上指定,如本例所示:

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

Builder 配置

如果 builder 暴露了配置选项,可以使用 environment 属性进行设置。

  • Groovy

  • Kotlin

tasks.named("bootBuildImage") {
	environment["BP_JVM_VERSION"] = "17"
}
tasks.named<BootBuildImage>("bootBuildImage") {
	environment.put("BP_JVM_VERSION", "17")
}

如果 builder 运行的 Docker 守护进程与 buildpacks 下载工件的网络位置之间存在网络代理,你需要配置 builder 使用该代理。使用 Paketo builder 时,可以通过设置 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.putAll(mapOf("HTTP_PROXY" to "http://proxy.example.com",
						"HTTPS_PROXY" to "https://proxy.example.com"))
}

运行时 JVM 配置

Paketo Java buildpacks 通过设置 JAVA_TOOL_OPTIONS 环境变量来配置 JVM 运行时环境。buildpack 提供的 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.putAll(mapOf(
		"BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
		"BPE_APPEND_JAVA_TOOL_OPTIONS" to "-XX:+HeapDumpOnOutOfMemoryError"
	))
}

自定义镜像名称

默认情况下,镜像名称根据项目的 nameversion 推断,例如 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}")
}

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

镜像名称也可以在命令行上指定,如本例所示:

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

Buildpacks

默认情况下,builder 将使用 builder 镜像中包含的 buildpacks 并按预定义的顺序应用它们。可以提供一组替代的 buildpacks,以应用未包含在 builder 中的 buildpacks,或更改包含的 buildpacks 的顺序。当提供一个或多个 buildpacks 时,只会应用指定的 buildpacks。

以下示例指示 builder 使用打包在 .tgz 文件中的自定义 buildpack,然后使用 builder 中包含的 buildpack。

  • 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"))
}

Buildpacks 可以以下述任一形式指定。

位于 CNB Builder 中的 buildpack (如果 builder 中只有一个与 buildpack-id 匹配的 buildpack,则可以省略版本)

包含 buildpack 内容的目录路径 (Windows 上不支持)

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

  • /path/to/buildpack/

包含 buildpack 内容的 gzipped tar 文件路径

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

  • /path/to/buildpack.tgz

包含打包 buildpack 的 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")
		}
	}
}

publish 选项也可以在命令行上指定,如本例所示:

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

Builder 缓存和工作空间配置

CNB builder 会缓存构建和启动镜像时使用的层。默认情况下,这些缓存作为命名卷存储在 Docker 守护进程中,其名称派生自目标镜像的完整名称。如果镜像名称频繁更改(例如将项目版本用作镜像名称中的 tag),则缓存可能会频繁失效。

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

  • 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")
		}
	}
}

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

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

  • 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 daemon 通信,而非默认的本地连接。

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

该插件也可以通过提供类似于以下示例中所示的连接详细信息来配置为使用 minikube daemon

  • 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 daemon 通信。可以使用以下命令设置 DOCKER_HOST 环境变量

$ export DOCKER_HOST=$(docker context inspect colima -f '{{.Endpoints.docker.Host}}')

该插件也可以通过提供类似于以下示例中所示的连接详细信息来配置为使用 Colima daemon。

  • 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 配置

如果 builder 或 run 镜像存储在支持用户身份验证的私有 Docker registry 中,可以使用 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]")
		}
	}
}

如果 builder 或 run 镜像存储在支持令牌身份验证的私有 Docker registry 中,可以使用 docker.builderRegistry 提供令牌值,如以下示例所示

  • Groovy

  • Kotlin

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