跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

镜像管理

最后更新 查看 MarkdownAgent 设置

Container 应用根据其调度策略以不同方式管理镜像。使用 durable_object 策略时,Durable Object 代码每次启动 Container 时选择镜像。使用 default 策略时,Wrangler 配置为应用设置一个镜像。

在 durable_object 调度策略中使用镜像

使用 Cloudflare 托管镜像

cloudflare/debian-trixie 托管镜像仅在 durable_object 调度策略下可用:

托管镜像 源镜像 内容
cloudflare/debian-trixie node:24.20.0-trixie-slim ↗ 按 digest 固定 Debian Trixie slim 上的 Node.js 24.20.0

cloudflare/debian-trixie 是 Cloudflare 托管标识符,不是公开的 Cloudflare Docker Hub 镜像。Durable Object 启动其 Container 时传入该标识符:

src/index.jsjs
this.ctx.container.start({
	image: "cloudflare/debian-trixie",
	enableInternet: false,
});
src/index.tsts
this.ctx.container.start({
	image: "cloudflare/debian-trixie",
	enableInternet: false,
});

配置具名镜像

在 images 映射中配置一个或多个具名镜像。每个条目必须恰好使用一个镜像源。设置 dockerfile 以从本地 Dockerfile 构建镜像。设置 image 以使用 Cloudflare 托管 registry 中按 digest 固定的镜像。

以下配置为每种源定义一个镜像:

{
	"containers": [
		{
			"class_name": "AgentComputer",
			"scheduling_policy": "durable_object",
			"images": {
				"base": {
					"dockerfile": "./container/Dockerfile",
					"build_context": ".",
				},
				"tools": {
					"image": "registry.cloudflare.com/<ACCOUNT_ID>/<REPOSITORY>@sha256:<DIGEST>",
				},
			},
		},
	],
}
[[containers]]
class_name = "AgentComputer"
scheduling_policy = "durable_object"

[containers.images.base]
dockerfile = "./container/Dockerfile"
build_context = "."

[containers.images.tools]
image = "registry.cloudflare.com/<ACCOUNT_ID>/<REPOSITORY>@sha256:<DIGEST>"

Wrangler 会构建或解析每个具名镜像,并通过 ctx.container.images 公开其按 digest 固定的引用。Durable Object 启动其 Container 时选择一个引用:

src/index.jsjs
import { DurableObject } from "cloudflare:workers";

export class AgentComputer extends DurableObject {
	startContainer() {
		this.ctx.container.start({
			image: this.ctx.container.images.base,
			instance: "standard-2",
			enableInternet: false,
		});
	}
}
src/index.tsts
import { DurableObject } from "cloudflare:workers";

export class AgentComputer extends DurableObject {
	startContainer() {
		this.ctx.container.start({
			image: this.ctx.container.images.base,
			instance: "standard-2",
			enableInternet: false,
		});
	}
}

一份配置最多可以包含 100 个具名镜像。每个镜像名称必须包含 1 到 128 个字符。完整策略配置请参阅调度策略。

推出具名镜像更新

要更新具名镜像,请更改其 Dockerfile,或将 image 设置为新的按 digest 固定的引用。然后部署 Worker。部署完成后,ctx.container.images 中的对应值会指向更新后的镜像。在 Workers 渐进式部署 期间,每个 Durable Object 看到的是运行它的 Worker 版本的镜像映射,因此在部署完成前,不同 Durable Object 可以启动不同镜像。

部署更新后的镜像映射不会重启正在运行的 Containers。正在运行的 Container 会继续使用其启动镜像。Durable Object 代码决定何时停止该 Container 并用更新后的引用启动它。这种由应用控制的重启,就是在 durable_object 策略下推出镜像变更的方式。

要让正在运行的 Container 保持当前镜像,仅在其下次启动时使用已配置镜像:

src/index.jsjs
if (!this.ctx.container.running) {
	this.ctx.container.start({
		image: this.ctx.container.images.base,
		instance: "standard-2",
		enableInternet: false,
	});
}
src/index.tsts
if (!this.ctx.container.running) {
	this.ctx.container.start({
		image: this.ctx.container.images.base,
		instance: "standard-2",
		enableInternet: false,
	});
}

要立即升级正在运行的 Container,请将其镜像与已配置镜像进行比较。当它们不同时,停止 Container 并用已配置镜像启动它。

inspect() 在 Container 正在启动时,以及从快照恢复的 Container 上,会报告空镜像。以下示例不会在这两种情况下替换 Container:

src/index.jsjs
const image = this.ctx.container.images.base;
const info = await this.ctx.container.inspect();

if (info && info.image !== "" && info.image !== image) {
	await this.ctx.container.destroy();
}

if (!this.ctx.container.running) {
	this.ctx.container.start({
		image,
		instance: "standard-2",
		enableInternet: false,
	});
}
src/index.tsts
const image = this.ctx.container.images.base;
const info = await this.ctx.container.inspect();

if (info && info.image !== "" && info.image !== image) {
	await this.ctx.container.destroy();
}

if (!this.ctx.container.running) {
	this.ctx.container.start({
		image,
		instance: "standard-2",
		enableInternet: false,
	});
}

使用外部镜像

要使用其他 registry 中的镜像,请拉取它并将其推送到 Cloudflare 托管 registry。然后,获取其 digest,并将生成的按 digest 固定的引用配置为具名镜像。

具名 dockerfile 条目可以在其 FROM 指令中使用外部镜像。如果基础镜像是私有的,请在部署前对本地 Docker 安装进行身份验证。

在 default 调度策略中使用镜像

将单一的 image 字段设置为本地 Dockerfile 或受支持的 registry 引用。更改此字段会通过应用范围的滚动发布部署新的应用镜像。

在 wrangler deploy 期间推送镜像

在运行 wrangler deploy 时,如果你在Wrangler 配置中将 image 属性设置为 Dockerfile 的路径,Wrangler 将使用 Docker 在本地构建你的容器镜像,然后将其推送到 Cloudflare 运行的 registry 中。 这个 registry 与你的 Cloudflare 账户集成,由 R2 提供支持。所有身份验证在推送和提取镜像时由 Cloudflare 自动处理。

只需提供指向 Dockerfile 的路径:

{
	"containers": [
		{
			"image": "./Dockerfile"
		}
	]
}
[[containers]]
image = "./Dockerfile"

然后通过 wrangler deploy 部署你的 Worker。不需要进行其他镜像管理。

在后续部署中,Wrangler 只会推送已更改的镜像层,这节省了空间和时间。

使用预构建的容器镜像

使用 default 调度策略时,Containers 支持来自由 Cloudflare 管理的 registry.cloudflare.com registry、Docker Hub ↗、Amazon ECR ↗ 和 Google Artifact Registry ↗ 的镜像。

使用公开的 Docker Hub 镜像

要使用公开的 Docker Hub 镜像,请在你的 Wrangler 配置中将 image 设置为一个完全限定的 Docker Hub 镜像引用。

例如:

{
	"containers": [
		{
			"image": "docker.io/<NAMESPACE>/<REPOSITORY>:<TAG>"
		}
	]
}
[[containers]]
image = "docker.io/<NAMESPACE>/<REPOSITORY>:<TAG>"

公开的 Docker Hub 镜像不需要配置 registry。

私有的 Docker Hub 镜像使用接下来介绍的私有 registry 配置流程。

如果已配置了 Docker Hub 凭证,这些凭证用于提取公开和私有镜像。

配置私有 registry 凭证

要使用 Docker Hub、Amazon ECR 或 Google Artifact Registry 的私有镜像,请针对 registry 域运行 wrangler containers registries configure。

Wrangler 会提示你输入 secret 并将其存储在 Secrets Store 中。如果你还没有 Secrets Store 存储,Wrangler 将首先提示你创建一个。

使用 --secret-name 来命名或重用一个 secret,--secret-store-id 以定位特定的 Secrets Store 存储,以及 --skip-confirmation 以进行非交互式运行。在 CI 或脚本中,通过 stdin 传递 secret。

使用私有的 Docker Hub 镜像

使用以下值在 Wrangler 中配置 Docker Hub:

  • registry 域:docker.io
  • 用户名标志:--dockerhub-username=<YOUR_DOCKERHUB_USERNAME>
  • secret:具有只读权限的 Docker Hub 个人访问令牌(PAT)

要创建 Docker Hub 个人访问令牌:

  1. 登录到 Docker 主页 ↗。
  2. 前往 Account settings(账户设置) > Personal access tokens(个人访问令牌)。
  3. 选择 Generate new token(生成新令牌)。
  4. 赋予该令牌 Read(读取) 权限,然后复制令牌值。

交互式:

npx wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME>

CI 或脚本:

printf '%s' "$DOCKERHUB_PAT" | npx wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME> --secret-name=<SECRET_NAME> --skip-confirmation

配置完 registry 后,使用上述展示的相同的完全限定的 Docker Hub 镜像引用。

使用私有 Amazon ECR 镜像

使用以下值在 Wrangler 中配置 Amazon ECR:

  • registry 域:<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
  • 访问密钥标志:--aws-access-key-id=<AWS_ACCESS_KEY_ID>
  • secret:匹配的 AWS 秘密访问密钥

不支持公开 ECR 镜像。 要生成所需凭证,创建一个带有只读策略的 IAM 用户。以下示例允许访问 us-east-1 中 AWS 账户 123456789012 内的所有镜像存储库。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": ["ecr:GetAuthorizationToken"],
			"Effect": "Allow",
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ecr:BatchCheckLayerAvailability",
				"ecr:GetDownloadUrlForLayer",
				"ecr:BatchGetImage"
			],
			// arn:${Partition}:ecr:${Region}:${Account}:repository/${Repository-name}
			"Resource": [
				"arn:aws:ecr:us-east-1:123456789012:repository/*"
				// "arn:aws:ecr:us-east-1:123456789012:repository/example-repo"
			]
		}
	]
}

创建 IAM 用户后,使用其凭证在 Wrangler 中配置 registry。如果尚不存在,Wrangler 会提示你创建一个 Secrets Store 存储,然后将 secret 存储在那里。

交互式:

npx wrangler containers registries configure <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com --aws-access-key-id=<AWS_ACCESS_KEY_ID>

CI 或脚本:

printf '%s' "$AWS_SECRET_ACCESS_KEY" | npx wrangler containers registries configure <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com --aws-access-key-id=<AWS_ACCESS_KEY_ID> --secret-name=<SECRET_NAME> --skip-confirmation

配置完 registry 后,在你的 Wrangler 配置中使用完全限定的 Amazon ECR 镜像引用:

{
	"containers": [
		{
			"image": "<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<REPOSITORY>:<TAG>"
		}
	]
}
[[containers]]
image = "<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<REPOSITORY>:<TAG>"

使用私有 Google Artifact Registry 镜像

使用以下值在 Wrangler 中配置 Google Artifact Registry:

  • registry 域:<REGION>-docker.pkg.dev
  • Google 服务账户电子邮件标志:--gar-email=<SERVICE_ACCOUNT_EMAIL>
  • secret:服务账户 JSON 密钥

公共凭证是服务账户电子邮件,通过 --gar-email 提供。它必须与服务账户密钥中的 client_email 字段匹配。

私有凭证是服务账户 JSON 密钥。 通过 stdin(文件路径、原始 JSON 或 base64)或交互式提示(文件路径或 base64)提供它。 Wrangler 将以 base64 编码形式把密钥存储在 Secrets Store 中。

要生成所需凭证,请创建一个具有 Artifact Registry Reader(Artifact Registry 读取者) 角色的服务账户并下载其 JSON 密钥:

  1. 在 Google Cloud 控制台 ↗ 中,转到 IAM & Admin(IAM 和管理) > Service Accounts(服务账号)。
  2. 选择 Create service account(创建服务账户),然后输入名称、ID 和可选描述。
  3. 授予该服务账户 Artifact Registry Reader(Artifact Registry 读取者) 角色,然后选择 Done(完成)。
  4. 选择服务账户,然后打开 Keys(密钥) 选项卡。
  5. 选择 Add key(添加密钥) > Create new key(创建新密钥),选择 JSON,然后选择 Create(创建)。该密钥文件会下载到你的机器上。

交互式: Wrangler 将提示输入密钥,你要在其中输入文件路径或经过 base64 编码的 JSON:

npx wrangler containers registries configure <REGION>-docker.pkg.dev --gar-email=<SERVICE_ACCOUNT_EMAIL>

CI 或脚本: 通过 stdin 传递密钥(将密钥内容作为原始 JSON 或 base64,或通过密钥文件路径)

cat <PATH_TO_KEY> | npx wrangler containers registries configure <REGION>-docker.pkg.dev --gar-email=<SERVICE_ACCOUNT_EMAIL> --secret-name=<SECRET_NAME> --skip-confirmation

如果你已经将密钥存储在 Secrets Store 中,请引用现有 secret 并省略该密钥:

npx wrangler containers registries configure <REGION>-docker.pkg.dev --gar-email=<SERVICE_ACCOUNT_EMAIL> --secret-name=<EXISTING_SECRET_NAME> --skip-confirmation

配置完 registry 后,在你的 Wrangler 配置中使用完全限定的 Google Artifact Registry 镜像引用:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "containers": [
    {
      "image": "<REGION>-docker.pkg.dev/<PROJECT_ID>/<REPOSITORY>/<IMAGE>:<TAG>"
    }
  ]
}
[[containers]]
image = "<REGION>-docker.pkg.dev/<PROJECT_ID>/<REPOSITORY>/<IMAGE>:<TAG>"

要使用上面未列出的 registry 中的镜像,请将其推送到 Cloudflare Registry。

将镜像推送到 Cloudflare Registry

两种调度策略都可以使用你自己推送到 Cloudflare Registry 的镜像。使用 durable_object 策略时,对于来自 Docker Hub、Amazon ECR、Google Artifact Registry 或其他外部 registry 的任何镜像,这都是必需的。

使用来自其他 registry 的镜像

如果你想使用来自另一个 registry 服务商的预构建镜像,请首先确保它在本地存在,然后将其推送到 Cloudflare Registry:

docker pull <PUBLIC_IMAGE>
docker tag <PUBLIC_IMAGE> <IMAGE>:<TAG>

Wrangler 提供了一个向 Cloudflare Registry 推送镜像的命令:

npx wrangler containers push <IMAGE>:<TAG>

或者,你可以将 -p 标志与 wrangler containers build 一起使用以一步完成镜像的构建和推送:

npx wrangler containers build -p -t <TAG> .

这将输出一个镜像 registry URI。使用 default 调度策略时,你可以在 Wrangler 配置中使用此标签引用:

{
	"containers": [
		{
			"image": "registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>:<TAG>"
		}
	]
}
[[containers]]
image = "registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>:<TAG>"

使用 durable_object 调度策略时,具名 image 源需要按 digest 固定的引用。请先获取已推送镜像的 digest。

获取已推送镜像的 digest

推送镜像后,使用 Docker 列出其仓库 digest:

docker image inspect --format '{{join .RepoDigests "\n"}}' registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>:<TAG>

将以 registry.cloudflare.com/ 开头的条目用作具名 image 源:

{
	"containers": [
		{
			"class_name": "AgentComputer",
			"scheduling_policy": "durable_object",
			"images": {
				"tools": {
					"image": "registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>@sha256:<DIGEST>",
				},
			},
		},
	],
}
[[containers]]
class_name = "AgentComputer"
scheduling_policy = "durable_object"

[containers.images.tools]
image = "registry.cloudflare.com/<YOUR_ACCOUNT_ID>/<IMAGE>@sha256:<DIGEST>"

借助 CI 推送镜像

要使用在持续集成环境中构建的镜像,请安装 wrangler,然后 使用带有 --push 标志的 wrangler containers build,或者 使用 wrangler containers push 命令来构建并推送镜像。使用 durable_object 调度策略时,请在更新 Wrangler 配置之前获取已推送镜像的 digest。

Registry 限制

镜像在大小上受制于为 Container 配置的实例类型的可用磁盘大小。

通过 wrangler containers images delete 删除镜像来释放空间,但是如果将使用被删除镜像的 Worker 恢复到以前的版本,将会出现错误。

这篇文档对您有帮助吗?