在本指南中,您将部署一个 Worker,它可以响应最终用户请求向一个或多个容器发出请求。 在此示例中,每个容器都运行一个用 Go 编写的小型 Web 服务器。
此示例 Worker 应该让您了解简单的容器使用,并为更复杂的用例提供起点。
在本指南中,我们将与您的 Worker 代码一起构建和推送容器镜像。默认情况下,此过程使用
Docker ↗ 来完成。当您运行 wrangler deploy
时,必须在本地运行 Docker。对于大多数人来说,安装 Docker 的最佳方式是遵循 Docker Desktop 安装文档 ↗。
您可以通过在终端中运行 docker info
命令来检查 Docker 是否正常运行。如果 Docker 正在运行,该命令将成功执行。如果 Docker 未运行,
docker info
命令将挂起或返回包含"Cannot connect to the Docker daemon"消息的错误。
运行以下命令从启动模板创建并部署带有容器的新 Worker:
npm create cloudflare@latest -- --template=cloudflare/templates/containers-template
当您想要部署 Worker 或容器代码的更改时,可以使用 Wrangler CLI 运行以下命令:
npx wrangler deploy
yarn wrangler deploy
pnpm wrangler deploy
当您运行 wrangler deploy
时,会发生以下事情:
- Wrangler 使用 Docker 构建您的容器镜像。
- Wrangler 将您的镜像推送到自动与您的 Cloudflare 账户集成的容器镜像注册表。
- Wrangler 部署您的 Worker,并配置 Cloudflare 的网络以准备生成您的容器实例
构建和推送通常在第一次部署时耗时最长。后续部署会更快,因为它们会重用缓存的镜像层 ↗。
部署后,运行以下命令来显示您的 Cloudflare 账户中的容器列表及其部署状态:
npx wrangler containers list
yarn wrangler containers list
pnpm wrangler containers list
使用以下命令查看部署到 Cloudflare 注册表的镜像:
npx wrangler containers images list
yarn wrangler containers images list
pnpm wrangler containers images list
现在,打开您的 Worker 的 URL。它应该类似于 https://hello-containers.YOUR_ACCOUNT_NAME.workers.dev
。
如果您向路径 /container/1
或 /container/2
发出请求,这些请求会被路由到特定的容器。
"/container/" 后面的每个不同路径都会路由到一个唯一的容器。
如果您向 /lb
发出请求,您将负载均衡请求到随机选择的 3 个容器中的一个。
您可以通过阅读每个请求的输出来确认此行为。
现在您已经部署了第一个容器,让我们解释一下您的 Worker 代码、配置文件、容器代码中发生了什么,以及请求是如何路由的。
传入的请求最初由 Worker 处理,然后传递给启用容器的持久对象(Durable Object)。
为了简化并减少样板代码,Cloudflare 作为 @cloudflare/containers
NPM 包的一部分提供了 Container
类 ↗。
您不必熟悉 Durable Objects 就能使用容器,但了解基础知识可能会有所帮助。
每个 Durable Object 与单个容器实例一起运行,管理其启动和停止,并且 可以通过端口与容器交互。容器可能在请求它们的 Worker 实例附近运行,但不一定。 有关详细信息,请参阅"如何选择位置"。
在简单的应用程序中,Durable Object 可能只是启动容器并将请求代理给它。
在更复杂的应用程序中,拥有启用容器的 Durable Objects 允许您将请求路由到单个有状态的容器 实例,管理容器生命周期,向容器传递自定义启动命令和环境变量,在容器状态更改时运行钩子 等等。
有关更多详细信息,请参阅 Durable Object 容器方法文档和
Container
类存储库 ↗。
您的 Wrangler 配置文件 定义了 Worker 和容器的配置:
{ "containers": [ { "max_instances": 10, "name": "hello-containers", "class_name": "MyContainer", "image": "./Dockerfile" } ], "durable_objects": { "bindings": [ { "name": "MY_CONTAINER", "class_name": "MyContainer" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": [ "MyContainer" ] } ]}
[[containers]]max_instances = 10name = "hello-containers"class_name = "MyContainer"image = "./Dockerfile"
[[durable_objects.bindings]]name = "MY_CONTAINER"class_name = "MyContainer"
[[migrations]]tag = "v1"new_sqlite_classes = ["MyContainer"]
关于此配置的要点:
image
指向 Dockerfile 或包含 Dockerfile 的目录。class_name
必须是一个 Durable Object 类名。max_instances
声明将运行的同时运行容器实例的最大数量。- Durable Object 必须使用
new_sqlite_classes
而不是new_classes
。
您的容器镜像必须能够在 linux/amd64
架构上运行,除此之外,几乎没有限制。
在您刚刚部署的示例中,它是一个简单的 Golang 服务器,使用
将在 Worker 中设置的 MESSAGE
环境变量和自动生成的
环境变量 CLOUDFLARE_DEPLOYMENT_ID
在端口 8080 上响应请求。
func handler(w http.ResponseWriter, r *http.Request) { message := os.Getenv("MESSAGE") instanceId := os.Getenv("CLOUDFLARE_DEPLOYMENT_ID")
fmt.Fprintf(w, "Hi, I'm a container and this is my message: %s, and my instance ID is: %s", message, instanceId)}
首先注意扩展了 Container
↗ 类的 MyContainer
:
export class MyContainer extends Container { defaultPort = 8080; sleepAfter = '10s'; envVars = { MESSAGE: 'I was passed in via the container class!', };
override onStart() { console.log('Container successfully started'); }
override onStop() { console.log('Container successfully shut down'); }
override onError(error: unknown) { console.log('Container error:', error); }}
这定义了容器的基本配置:
defaultPort
设置fetch
和containerFetch
方法用于与容器通信的端口。它还会阻止 请求,直到容器在此端口上监听。sleepAfter
设置容器在空闲一定时间后进入睡眠的超时时间。envVars
设置容器启动时将传递给容器的环境变量。onStart
、onStop
和onError
是分别在容器启动、停止或出错时运行的钩子。
有关更多详细信息和配置选项,请参阅容器类文档。
当请求进入 Cloudflare 时,会调用您的 Worker 的 fetch
处理程序。这是处理传入请求的代码。示例代码中的 fetch 处理程序在不同路由上以两种方式启动容器:
-
向
/container/
发出请求会为每个路径将请求传递给新容器。这是通过启动新的容器实例来完成的。您可能会注意到 对新路径的第一个请求比后续请求花费更长时间,这是 因为新容器正在启动。if (pathname.startsWith("/container")) {const id = env.MY_CONTAINER.idFromName(pathname);const container = env.MY_CONTAINER.get(id);return await container.fetch(request);} -
向
/lb
发出请求将在多个容器之间负载均衡请求。 这使用了一个简单的getRandom
辅助方法,该方法从设定数量(在本例中为 3)中随机选择一个 ID,然后路由到该容器实例。您可以用任何您选择实现的路由或负载均衡逻辑替换它:if (pathname.startsWith("/lb")) {const container = await getRandom(env.MY_CONTAINER, 3);return await container.fetch(request);}
这允许使用容器的多种方式:
- 如果您只是想向许多无状态且可互换的容器发送请求, 您应该使用负载均衡。
- 如果您有有状态服务或需要单独可寻址的 容器,您应该请求特定的容器实例。
- 如果您正在运行短期作业,希望对容器 生命周期进行细粒度控制,想要参数化容器入口点或环境变量,或 想要将多个容器调用链接在一起,您应该请求特定的 容器实例。
容器控制面板 ↗ 向您显示有关容器的有用 信息,包括:
- 状态和健康状况
- 指标
- 日志
- 指向关联 Workers 和 Durable Objects 的链接
启动 Worker 后,通过单击侧边栏中"Workers & Pages"下的"Containers" 导航到容器控制面板。
要做更多:
- 通过更改 Dockerfile 并调用
wrangler deploy
来修改镜像 - 查看我们的示例以获得更多灵感
- 获取有关容器 Beta 版的更多信息
- @2025 Cloudflare Ubitools
- Cf Repo