Image Management
Last updated Sep 30, 2026
Container applications manage images differently based on their scheduling policy. With the durable_object policy, Durable Object code selects an image each time it starts a Container. With the default policy, Wrangler configuration sets one image for the application.
Use images with the durable_object scheduling policy
Use the Cloudflare-managed image
The cloudflare/debian-trixie managed image is available only with the durable_object scheduling policy:
| Managed image | Source image | Contents |
|---|---|---|
cloudflare/debian-trixie |
node:24.20.0-trixie-slim ↗︎ pinned by digest |
Node.js 24.20.0 on Debian Trixie slim |
cloudflare/debian-trixie is a Cloudflare-managed identifier, not a public Cloudflare Docker Hub image. Pass the identifier when the Durable Object starts its 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,
});
Configure named images
Configure one or more named images in the images map. Each entry must use exactly one image source. Set dockerfile to build an image from a local Dockerfile. Set image to use a digest-pinned image from the Cloudflare managed registry.
The following configuration defines one image from each source:
{
"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 builds or resolves each named image and exposes its digest-pinned reference through ctx.container.images. Select a reference when the Durable Object starts its 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,
});
}
}
A configuration can contain up to 100 named images. Each image name must contain between 1 and 128 characters. For the complete policy configuration, refer to Scheduling Policies.
Roll out a named image update
To update a named image, change its Dockerfile or set image to a new digest-pinned reference. Then, deploy the Worker. After the deployment completes, the corresponding value in ctx.container.images refers to the updated image. During a Workers gradual deployment, each Durable Object sees the image map of the Worker version that runs it, so different Durable Objects can start different images until the deployment completes.
Deploying an updated image map does not restart running Containers. A running Container continues to use its startup image. Durable Object code decides when to stop that Container and start it with the updated reference. This application-controlled restart is how you roll out image changes with the durable_object policy.
To keep a running Container on its current image, use the configured image only on its next start:
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,
});
}
To upgrade a running Container immediately, compare its image with the configured image. When they differ, stop the Container and start it with the configured image.
inspect() reports an empty image while a Container is starting and for a Container restored from a snapshot. The following example does not replace a Container in either case:
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,
});
}
Caution
destroy() stops the Container immediately. In-progress work and any filesystem changes made since startup are lost. To preserve the filesystem, create a snapshot before you stop the Container. A snapshot is tied to the image it was created from, so you cannot restore it onto the updated image.
Use an external image
Note
The durable_object scheduling policy does not support direct image references from external registries. A named image source must use a digest-pinned reference from the Cloudflare managed registry.
To use an image from another registry, pull it and push it to the Cloudflare managed registry. Then, get its digest and configure the resulting digest-pinned reference as a named image.
A named dockerfile entry can use an external image in its FROM instruction. Authenticate your local Docker installation before deploying if the base image is private.
Use images with the default scheduling policy
Set the singular image field to a local Dockerfile or a supported registry reference. Changing this field deploys the new application image through an application-wide rollout.
Push images during wrangler deploy
When running wrangler deploy, if you set the image attribute in your Wrangler configuration to a path to a Dockerfile, Wrangler will build your container image locally using Docker, then push it to a registry run by Cloudflare. This registry is integrated with your Cloudflare account and is backed by R2. All authentication is handled automatically by Cloudflare both when pushing and pulling images.
Just provide the path to your Dockerfile:
{
"containers": [
{
"image": "./Dockerfile"
}
]
}
[[containers]]
image = "./Dockerfile"
And deploy your Worker with wrangler deploy. No other image management is necessary.
On subsequent deploys, Wrangler will only push image layers that have changed, which saves space and time.
Note
Docker or a Docker-compatible CLI tool must be running for Wrangler to build and push images. This is not necessary if you are using a pre-built image, as described below.
Use pre-built container images
With the default scheduling policy, Containers support images from the Cloudflare managed registry at registry.cloudflare.com, Docker Hub ↗︎, Amazon ECR ↗︎, and Google Artifact Registry ↗︎.
Note
Cloudflare does not cache images pulled from Docker Hub, Amazon ECR, or Google Artifact Registry.
Docker Hub pulls may be subject to Docker Hub pull limits or fair-use restrictions. Pulling images from Amazon ECR or Google Artifact Registry may incur cloud provider egress charges.
Note
The durable_object scheduling policy does not pull from Docker Hub, Amazon ECR, or Google Artifact Registry, and does not use registry credentials configured with wrangler containers registries configure. Refer to Use an external image.
Use public Docker Hub images
To use a public Docker Hub image, set image to a fully qualified Docker Hub image reference in your Wrangler configuration.
For example:
{
"containers": [
{
"image": "docker.io/<NAMESPACE>/<REPOSITORY>:<TAG>"
}
]
}
[[containers]]
image = "docker.io/<NAMESPACE>/<REPOSITORY>:<TAG>"
Public Docker Hub images do not require registry configuration.
Private Docker Hub images use the private registry configuration flow described next.
If Docker Hub credentials have been configured, those credentials are used to pull both public and private images.
Note
Official Docker Hub images use the library namespace. For example, use docker.io/library/<IMAGE>:<TAG> instead of docker.io/<IMAGE>:<TAG>.
Configure private registry credentials
To use a private image from Docker Hub, Amazon ECR, or Google Artifact Registry, run wrangler containers registries configure for the registry domain.
Wrangler prompts for the secret and stores it in Secrets Store. If you do not already have a Secrets Store store, Wrangler prompts you to create one first.
Use --secret-name to name or reuse a secret, --secret-store-id to target a specific Secrets Store store, and --skip-confirmation for non-interactive runs. In CI or scripts, pass the secret through stdin.
Use private Docker Hub images
Configure Docker Hub in Wrangler using these values:
- registry domain:
docker.io - username flag:
--dockerhub-username=<YOUR_DOCKERHUB_USERNAME> - secret: Docker Hub personal access token with read-only access
To create a Docker Hub personal access token:
- Sign in to Docker Home ↗︎.
- Go to Account settings > Personal access tokens.
- Select Generate new token.
- Give the token Read access, then copy the token value.
Interactive:
npmyarnpnpm
npx wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME>
yarn wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME>
pnpm wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME>
CI or scripts:
printf '%s' "$DOCKERHUB_PAT" | npx wrangler containers registries configure docker.io --dockerhub-username=<YOUR_DOCKERHUB_USERNAME> --secret-name=<SECRET_NAME> --skip-confirmation
