打包 OCI 镜像

该插件可以使用 云原生构建包 (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 配置文件 中检索主机信息的 上下文 的名称。

主机

包含 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 镜像仓库的地址。用户身份验证可选。

email

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

token

Docker 镜像仓库用户的身份令牌。令牌身份验证必填。

更多详细信息,另请参阅 示例

镜像自定义

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

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

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

builder

--builder

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

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

runImage

--runImage

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

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

imageName

--imageName

生成的镜像的 镜像名称

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

pullPolicy

--pullPolicy

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

ALWAYS

environment

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

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

buildpacks

构建器在构建镜像时应使用的构建包。仅使用指定的构建包,覆盖构建器中包含的默认构建包。构建包引用必须采用以下其中一种形式:

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

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

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

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

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

bindings

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

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

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

其中 <选项> 可以包含:

  • ro 以只读方式将卷挂载到容器中。

  • rw 以可读写方式将卷挂载到容器中。

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

network

--network

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

cleanCache

--cleanCache

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

false

verboseLogging

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

false

publish

--publishImage

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

false

tags

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

buildWorkspace

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

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

buildCache

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

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

launchCache

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

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

createdDate

--createdDate

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

一个固定日期,可启用 构建可重复性

applicationDirectory

--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.put("BP_JVM_VERSION", "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.putAll(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.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}")
}

请注意,此配置未提供显式标签,因此使用 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/

包含构建包内容的 gzipped 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守护进程通信。可以使用以下命令设置DOCKER_HOST环境变量

$ export DOCKER_HOST=$(docker context inspect colima -f '{{.Endpoints.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...")
		}
	}
}