From 63506c724e095f08d7de885a69e1f26aa35b7449 Mon Sep 17 00:00:00 2001 From: Greg Anders Date: Thu, 26 Mar 2026 16:05:32 -0500 Subject: [PATCH 01/73] Add docs and changelog for containers snapshots --- .../containers/2026-09-03-snapshots.mdx | 56 +++++++++++++++ .../docs/containers/concepts/architecture.mdx | 11 +-- src/content/docs/containers/faq.mdx | 9 +-- .../docs/containers/guides/snapshots.mdx | 71 +++++++++++++++++++ 4 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 src/content/changelog/containers/2026-09-03-snapshots.mdx create mode 100644 src/content/docs/containers/guides/snapshots.mdx diff --git a/src/content/changelog/containers/2026-09-03-snapshots.mdx b/src/content/changelog/containers/2026-09-03-snapshots.mdx new file mode 100644 index 00000000000..ff8924d1388 --- /dev/null +++ b/src/content/changelog/containers/2026-09-03-snapshots.mdx @@ -0,0 +1,56 @@ +--- +title: Snapshot and restore Container state +description: Persist point-in-time container filesystem with experimental snapshot APIs. +products: + - containers +date: 2026-09-03 +--- + +import { TypeScriptExample } from "~/components"; + +[Containers](/containers/) now support experimental snapshot APIs for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. + +Use `snapshotContainer()` to capture the full container filesystem. The example uses the [low-level Durable Object container API](/durable-objects/api/container/). Create snapshots from a container that is already running: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class MyDurableObject extends DurableObject { + async saveSnapshot() { + const containerSnapshot = await this.ctx.container.snapshotContainer({}); + + await this.ctx.storage.put("containerSnapshot", containerSnapshot); + } +} +``` + + + +Later, load the saved snapshot handle and restore it with `start()`: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class MyDurableObject extends DurableObject { + async restoreSnapshot() { + const containerSnapshot = + await this.ctx.storage.get("containerSnapshot"); + + if (!containerSnapshot) { + return; + } + + this.ctx.container.start({ containerSnapshot }); + } +} +``` + + + +Snapshots are immutable. + +For more information, refer to [Snapshots](/containers/guides/snapshots/) and [Durable Object Container](/durable-objects/api/container/). diff --git a/src/content/docs/containers/concepts/architecture.mdx b/src/content/docs/containers/concepts/architecture.mdx index dbdd81beb46..9ccdc161984 100644 --- a/src/content/docs/containers/concepts/architecture.mdx +++ b/src/content/docs/containers/concepts/architecture.mdx @@ -145,13 +145,14 @@ The [`Container` class](/containers/api/container-class/) adds hooks that run Wo Refer to the [status hooks example](/containers/examples/status-hooks/) for a full implementation. -#### Persistent disk +#### Use snapshots -All disk is ephemeral. When a Container instance goes to sleep, the next time -it is started, it will have a fresh disk as defined by its container image. +All disk is ephemeral by default. When a Container instance goes to sleep, the +next time it starts, it uses a fresh disk from the container image. -Snapshots are coming soon, which allow the user to quickly persist and restore the disk -from an entire container or a directory. +If you need point-in-time filesystem state, create and restore a snapshot. +Snapshots are immutable, so later file changes require a new snapshot. For more +information, refer to [Snapshots](/containers/guides/snapshots/). You can also use [FUSE](/containers/examples/r2-fuse-mount/) to persist disk to R2 or other object storage backends. Though you should not expect native diff --git a/src/content/docs/containers/faq.mdx b/src/content/docs/containers/faq.mdx index 94ddc8be3f1..9c0aaa765a0 100644 --- a/src/content/docs/containers/faq.mdx +++ b/src/content/docs/containers/faq.mdx @@ -104,11 +104,12 @@ Refer to [image management](/containers/guides/image-management/#use-pre-built-c ## Is disk persistent? What happens to my disk when my container sleeps? -All disk is ephemeral. When a Container instance goes to sleep, the next time -it is started, it will have a fresh disk as defined by its container image. +All disk is ephemeral by default. When a Container instance goes to sleep, the +next time it starts, it uses a fresh disk from the container image. -Snapshots are coming soon, which allow the user to quickly persist and restore the disk -from an entire container or a directory. +If you need point-in-time filesystem state, create and restore a snapshot. +Snapshots are immutable, so later file changes require a new snapshot. For more +information, refer to [Snapshots](/containers/guides/snapshots/). You can also use [FUSE](/containers/examples/r2-fuse-mount/) to persist disk to R2 or other object storage backends. Though you should not expect native diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx new file mode 100644 index 00000000000..2a2f8ca8037 --- /dev/null +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -0,0 +1,71 @@ +--- +title: Use snapshots +pcx_content_type: how-to +sidebar: + order: 7 +description: Persist container filesystem across restarts. +--- + +import { TypeScriptExample } from "~/components"; + +Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [low-level Durable Object container API](/durable-objects/api/container/). + +## Create a container snapshot + +Use `snapshotContainer()` to capture the full container filesystem. Snapshots are immutable. If you restore a snapshot and then change files, create a new snapshot to persist those changes. + +The returned snapshot handle is a plain data object. You can store it and restore it later, including from another Durable Object: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class MyDurableObject extends DurableObject { + async saveContainer() { + const containerSnapshot = await this.ctx.container.snapshotContainer({ + name: "before-upgrade", + }); + + await this.ctx.storage.put("containerSnapshot", containerSnapshot); + } +} +``` + + + +## Restore a container snapshot + +Load the saved snapshot handle. Then, pass it to `this.ctx.container.start()` when you start another container: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class MyDurableObject extends DurableObject { + async restoreContainer() { + const containerSnapshot = + await this.ctx.storage.get("containerSnapshot"); + + if (!containerSnapshot) { + return; + } + + this.ctx.container.start({ containerSnapshot }); + } +} +``` + + + +## Understand retention + +Snapshots currently have an implicit 30-day time-to-live. Each restore refreshes that time-to-live. + +You cannot set a custom time-to-live yet. + +## Related resources + +- [Durable Object Container](/durable-objects/api/container/) - Full `ctx.container` API reference +- [Lifecycle of a Container](/containers/concepts/architecture/) - Understand startup, sleep, and shutdown behavior From dd5c049a31dd33069bad07cf42e2c1e673a92126 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Fri, 18 Sep 2026 11:46:57 -0400 Subject: [PATCH 02/73] [Containers] Document Durable Object scheduling policy --- ...09-28-durable-object-scheduling-policy.mdx | 50 +++++ .../docs/containers/concepts/architecture.mdx | 21 +-- .../docs/containers/configuration/index.mdx | 2 +- .../containers/configuration/rollouts.mdx | 4 + .../configuration/scheduling-policy.mdx | 171 ++++++++++++++++++ .../containers/guides/image-management.mdx | 4 + src/content/docs/containers/index.mdx | 8 + .../docs/containers/platform/limits.mdx | 6 +- .../docs/workers/wrangler/configuration.mdx | 58 +++++- 9 files changed, 305 insertions(+), 19 deletions(-) create mode 100644 src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx create mode 100644 src/content/docs/containers/configuration/scheduling-policy.mdx diff --git a/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx new file mode 100644 index 00000000000..dae009399cd --- /dev/null +++ b/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx @@ -0,0 +1,50 @@ +--- +title: Configure Container image and instance size at runtime +description: The durable_object scheduling policy gives each Durable Object control of Container configuration. +products: + - containers +date: 2026-09-28 +--- + +import { TypeScriptExample, WranglerConfig } from "~/components"; + +[Containers](/containers/) now support the `durable_object` scheduling policy in public beta. This policy lets a Durable Object select the image and instance size for a Container at runtime instead of using one centrally managed configuration for the application. + +Configure the policy and one or more named images in Wrangler: + + + +```jsonc +{ + "containers": [ + { + "class_name": "AgentComputer", + "scheduling_policy": "durable_object", + "images": { + "base": { + "dockerfile": "./container/Dockerfile", + }, + }, + }, + ], +} +``` + + + +Wrangler prepares each image and exposes its immutable reference through `ctx.container.images`. Supply that reference and an instance size when you start the Container: + + + +```ts +this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", +}); +``` + + + +Durable Object-managed Container instances have independent lifecycles and do not participate in application-wide image rollouts. The existing `default` policy and its rollout behavior are unchanged. + +For configuration, runtime sizing, snapshots, and update behavior, refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). diff --git a/src/content/docs/containers/concepts/architecture.mdx b/src/content/docs/containers/concepts/architecture.mdx index 9ccdc161984..25699283ded 100644 --- a/src/content/docs/containers/concepts/architecture.mdx +++ b/src/content/docs/containers/concepts/architecture.mdx @@ -10,12 +10,13 @@ products: ## Deployment -After you deploy an application with a Container, your image is uploaded to -[Cloudflare's Registry](/containers/guides/image-management/) and distributed globally to Cloudflare's Network. -Cloudflare will pre-schedule instances and pre-fetch images across the globe to ensure quick start -times when scaling up the number of concurrent container instances. +How images and running Container instances update depends on the [scheduling policy](/containers/configuration/scheduling-policy/) for the application. -Worker code goes live on deploy. Container instances update with a [rollout](/containers/configuration/rollouts/). Refer to [Deploy Containers](/containers/guides/deploy/). +With the `default` policy, Wrangler uploads or resolves the application image. Cloudflare distributes that image across its network and prepares capacity for new instances. Changes to the image or instance type use a [rollout](/containers/configuration/rollouts/). + +With the `durable_object` policy, Wrangler prepares the named images for the application. Durable Object code can access their immutable references. The code selects an image and instance size when it calls `ctx.container.start()`. Running instances do not participate in application-wide image rollouts. + +Worker code goes live on deploy before any application-wide Container rollout finishes. Refer to [Deploy Containers](/containers/guides/deploy/). ## Container instance lifecycle @@ -70,8 +71,7 @@ developers to address and route to specific container instances, run code when a ### Starting a Container -When a Durable Object instance requests to start a new container instance, the **nearest location -with a pre-fetched image** is selected. +When a Durable Object requests a new Container instance, Cloudflare selects eligible capacity with the required image available. The `default` policy uses the application image and instance type from Wrangler configuration. The `durable_object` policy uses the `image` and `instance` options supplied to `ctx.container.start()`. :::note Durable Objects and their associated Container instances are not guaranteed to run in the @@ -81,12 +81,7 @@ Container placement is optimized for request routing and startup speed, so a Con start in a different location than its Durable Object. ::: -Starting additional container instances will use other locations with pre-fetched images, -and Cloudflare will automatically begin prepping additional machines behind the scenes -for additional scaling and quick cold starts. Because there are a finite number of pre-warmed -locations, some container instances may be started in locations that are farther away from -the end-user. This is done to ensure that the container instance starts quickly. You are -only charged for actively running instances and not for any unused pre-warmed images. +Starting additional Container instances can use other locations where the image is available. Cloudflare prepares additional capacity as demand grows. Because prepared capacity is finite, some Container instances may start in locations farther from the end user. You are only charged for actively running instances, not for prepared images that are not running. #### Cold starts diff --git a/src/content/docs/containers/configuration/index.mdx b/src/content/docs/containers/configuration/index.mdx index 787c7a1766a..4b06ca82c16 100644 --- a/src/content/docs/containers/configuration/index.mdx +++ b/src/content/docs/containers/configuration/index.mdx @@ -1,7 +1,7 @@ --- pcx_content_type: navigation title: Configuration -description: Configure Containers in Wrangler, connect them to Workers and bindings, set environment variables, tune scaling and routing, and manage rollouts. +description: Choose a scheduling policy, connect Containers to Workers and bindings, set environment variables, tune scaling and routing, and manage rollouts. sidebar: order: 5 group: diff --git a/src/content/docs/containers/configuration/rollouts.mdx b/src/content/docs/containers/configuration/rollouts.mdx index cb9b73c551c..c283d3522c0 100644 --- a/src/content/docs/containers/configuration/rollouts.mdx +++ b/src/content/docs/containers/configuration/rollouts.mdx @@ -10,6 +10,10 @@ products: import { WranglerConfig, PackageManagers } from "~/components"; +:::note +Rollouts apply to Container applications that use the [`default` scheduling policy](/containers/configuration/scheduling-policy/). Durable Object-managed Container instances do not participate in application-wide rollouts; application code selects their image when it calls `ctx.container.start()`. +::: + ## How rollouts work A **rollout** applies a target container application configuration after you [deploy](/containers/guides/deploy/) a Worker that uses Containers. The target can change the image, instance type, limits, placement, or other container settings. diff --git a/src/content/docs/containers/configuration/scheduling-policy.mdx b/src/content/docs/containers/configuration/scheduling-policy.mdx new file mode 100644 index 00000000000..db3913c70be --- /dev/null +++ b/src/content/docs/containers/configuration/scheduling-policy.mdx @@ -0,0 +1,171 @@ +--- +pcx_content_type: concept +title: Scheduling Policies +description: Choose whether Container configuration is managed centrally or by each Durable Object at runtime. +sidebar: + order: 1 +products: + - containers +--- + +import { TypeScriptExample, WranglerConfig } from "~/components"; + +A scheduling policy determines where you configure a Container image and instance size. It also determines how image updates apply. Choose the policy when you create the Container application. + +| Policy | Configure image and instance size | Image updates | Best for | +| - | - | - | - | +| `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | +| `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | + +The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. + +:::note +The `durable_object` scheduling policy is in public beta. +::: + +## Use the default scheduling policy + +The `default` policy preserves the existing Containers behavior. Define one `image`, one `instance_type`, and application-level settings such as `max_instances` in Wrangler configuration. Omitting `scheduling_policy` selects `default`. + + + +```jsonc +{ + "containers": [ + { + "class_name": "ApiContainer", + "scheduling_policy": "default", + "image": "./api/Dockerfile", + "instance_type": "standard-1", + "max_instances": 5, + }, + ], +} +``` + + + +When you change the image or instance type and deploy, Cloudflare rolls out that change across the application. Refer to [Rollouts](/containers/configuration/rollouts/). + +## Use the Durable Object scheduling policy + +The `durable_object` policy moves per-instance decisions into your Durable Object. Wrangler associates the Container application with the Durable Object class, and your code supplies a startup image or snapshot and an optional instance size to `ctx.container.start()`. + +Configure the policy and the images that the Durable Object can start: + + + +```jsonc +{ + "name": "agent-computer", + "main": "src/index.ts", + "compatibility_date": "$today", + "containers": [ + { + "class_name": "AgentComputer", + "scheduling_policy": "durable_object", + "images": { + "base": { + "dockerfile": "./container/Dockerfile", + }, + }, + }, + ], + "durable_objects": { + "bindings": [ + { + "name": "AGENT_COMPUTER", + "class_name": "AgentComputer", + }, + ], + }, + "migrations": [ + { + "tag": "v1", + "new_sqlite_classes": ["AgentComputer"], + }, + ], +} +``` + + + +Wrangler builds or resolves each named image, prepares it for the Containers runtime, and exposes its digest-pinned reference on `ctx.container.images`. Select an image and instance size when the Durable Object starts its Container: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class AgentComputer extends DurableObject { + startContainer() { + if (this.ctx.container.running) { + return; + } + + this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + enableInternet: true, + }); + } +} +``` + + + +`ctx.container.start()` initiates startup and returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic or calling [`exec()`](/durable-objects/api/container/#exec). + +### Configure named images + +Each key in `images` is a name you choose. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. Wrangler builds and uploads the image. You can also set `build_context` and `build_vars` for that image. + +Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. + +A configuration can contain up to 100 named images. An image name must contain between 1 and 128 characters. + +The image map is uploaded with the Worker version. Updating the map does not restart or replace running Container instances. Your application selects an image from the map when it starts an instance. + +### Choose an instance size at runtime + +Set `instance` in `ctx.container.start()` to one of the following named instance types: + +- `lite` +- `standard-1` +- `standard-2` +- `standard-3` +- `standard-4` + +If you omit `instance`, the Container uses `lite`. You can also supply a custom instance object: + +```ts +this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: { + vcpu: 1, + memoryMib: 4096, + diskMb: 8000, + }, +}); +``` + +The runtime uses camel case (`memoryMib` and `diskMb`). Wrangler's application-level `instance_type` object uses snake case (`memory_mib` and `disk_mb`) and only applies to the `default` policy. Refer to [Limits and Instance Types](/containers/platform/limits/). + +### Start from an image or snapshot + +For a new filesystem, pass `image` to `ctx.container.start()`. To restore a full filesystem snapshot, pass `containerSnapshot` instead. `image` and `containerSnapshot` are mutually exclusive because a snapshot already identifies the filesystem to restore. + +Refer to [Snapshots](/containers/guides/snapshots/) for the complete save and restore flow. + +### Manage updates from application code + +Container instances that use the `durable_object` policy do not participate in application-wide image rollouts. A running instance continues to use its startup image. Your application decides when to stop that instance and start it with another configured image. + +One Wrangler configuration can contain applications with both policies. This lets a Worker use centrally managed service Containers alongside Durable Object-managed sandboxes. + +## Related resources + +- [Durable Object Container API](/durable-objects/api/container/) +- [Lifecycle of a Container](/containers/concepts/architecture/) +- [Image Management](/containers/guides/image-management/) +- [Wrangler Containers configuration](/workers/wrangler/configuration/#containers) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index dff2c55fdca..edd0e235459 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -10,6 +10,10 @@ products: import { WranglerConfig, PackageManagers, Steps } from "~/components"; +:::note +The `image` examples on this page apply to Container applications that use the [`default` scheduling policy](/containers/configuration/scheduling-policy/). For the `durable_object` policy, configure a named `images` map and select an image from `ctx.container.images` at runtime. A named `image` entry must be a digest-pinned reference in the Cloudflare managed registry; a named `dockerfile` entry can build from an external base image. +::: + ## Push images during `wrangler deploy` When running `wrangler deploy`, if you set the `image` attribute in your [Wrangler configuration](/workers/wrangler/configuration/#containers) to a path to a Dockerfile, Wrangler will build your container image locally using Docker, then push it to a registry run by Cloudflare. diff --git a/src/content/docs/containers/index.mdx b/src/content/docs/containers/index.mdx index a8c4dd0a0c4..ac9727f47d3 100644 --- a/src/content/docs/containers/index.mdx +++ b/src/content/docs/containers/index.mdx @@ -221,6 +221,14 @@ Ship from your machine or Workers Builds, and confirm the deploy. + + Choose whether image and instance configuration is managed centrally or from Durable Object code. + + -These are specified using the [`instance_type` property](/workers/wrangler/configuration/#containers) in your Worker's Wrangler configuration file. +For an application that uses the [`default` scheduling policy](/containers/configuration/scheduling-policy/), specify the size with the [`instance_type` property](/workers/wrangler/configuration/#containers) in your Worker's Wrangler configuration file. For the `durable_object` policy, pass the named size to `ctx.container.start()` with the runtime `instance` property. :::note The `dev` and `standard` instance types are preserved for backward compatibility and are aliases for `lite` and `standard-1`, respectively. @@ -24,7 +24,9 @@ The `dev` and `standard` instance types are preserved for backward compatibility ### Custom Instance Types -In addition to the predefined instance types, you can configure custom instance types by specifying `vcpu`, `memory_mib`, and `disk_mb` values. See the [Wrangler configuration documentation](/workers/wrangler/configuration/#custom-instance-types) for configuration details. +In addition to the predefined instance types, you can configure custom instance types. Field names depend on where you configure the size. Wrangler configuration for the `default` policy uses `vcpu`, `memory_mib`, and `disk_mb`. A `ctx.container.start()` call for the `durable_object` policy uses `vcpu`, `memoryMib`, and `diskMb`. + +Refer to the [Wrangler configuration documentation](/workers/wrangler/configuration/#custom-instance-types) or [scheduling policy documentation](/containers/configuration/scheduling-policy/#choose-an-instance-size-at-runtime) for examples. Custom instance types have the following constraints: diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 8a3a9335131..d5e69dc9f34 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1309,6 +1309,8 @@ You can also configure `run_worker_first` with an array of route patterns: You can define [Containers](/containers) to run alongside your Worker using the `containers` field. +Each Container application has a [scheduling policy](/containers/configuration/scheduling-policy/) that determines whether image and instance configuration is managed centrally or supplied by Durable Object code at runtime. The policy is immutable after the application is created. + :::note You must also define a Durable Object to communicate with your Container via Workers. This Durable Object's class name must match the `class_name` value in container configuration. @@ -1316,19 +1318,26 @@ class name must match the `class_name` value in container configuration. The following options are available: -- `image` +- `scheduling_policy` + - `"default"` uses the centrally configured application image, instance type, limits, and rollouts. This is the default when the field is omitted. + - `"durable_object"` lets each Durable Object supply its Container image and instance size to `ctx.container.start()`. Refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). +- `image` - The image to use for the container. This can either be a local path to a `Dockerfile`, in which case `wrangler deploy` will build and push the image, or it can be an image reference. Supported registries are the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry. For more information, refer to [Image Management](/containers/guides/image-management/). +- `images` + - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. + - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. - `class_name` - The corresponding Durable Object class name. This will make this Durable Object a container-enabled Durable Object and allow each instance to control a container. Refer to the [Durable Object Container API](/containers/api/durable-object-container/) for details. - `instance_type` - - The instance type of the container. This determines the amount of memory, CPU, and disk given to the container + - The instance type for the `default` policy. This determines the amount of memory, CPU, and disk given to the container instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, see the [instance types documentation](/containers/platform/limits/#instance-types). + - For the `durable_object` policy, set the runtime `instance` option in `ctx.container.start()` instead. - To specify a custom instance type, see [here](#custom-instance-types). - `max_instances` - - The maximum number of concurrent container instances you want to run at any given moment. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. + - The maximum number of concurrent container instances for the `default` policy. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. - Defaults to 20. - This value is only enforced when running in production on Cloudflare's network. This limit does not apply during local development, so you may run more instances than specified. - `name` @@ -1362,6 +1371,7 @@ The following options are available: "containers": [ { "class_name": "MyContainer", + "scheduling_policy": "default", "image": "./Dockerfile", "max_instances": 10, "instance_type": "basic", // Optional, defaults to "lite" @@ -1393,6 +1403,48 @@ The following options are available: +For the `durable_object` policy, name one or more images and select one from Durable Object code when the Container starts: + + + +```jsonc +{ + "containers": [ + { + "class_name": "AgentComputer", + "scheduling_policy": "durable_object", + "images": { + "base": { + "dockerfile": "./container/Dockerfile", + "build_context": ".", + "build_vars": { + "APP_ENV": "production", + }, + }, + }, + }, + ], + "durable_objects": { + "bindings": [ + { + "name": "AGENT_COMPUTER", + "class_name": "AgentComputer", + }, + ], + }, + "migrations": [ + { + "tag": "v1", + "new_sqlite_classes": ["AgentComputer"], + }, + ], +} +``` + + + +Only policy-level fields such as `name`, `class_name`, `scheduling_policy`, and `images` apply to a Durable Object-managed entry. Configure its image and instance size in `ctx.container.start()` instead of setting `image`, `instance_type`, or rollout fields here. + ### Custom Instance Types In place of the [named instance types](/containers/platform/limits/#instance-types), you can set a custom instance type by individually configuring vCPU, memory, and disk. From aa34d087d2ce2156a8a52ab36fa03af5ca608a71 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:08:24 -0400 Subject: [PATCH 03/73] [Containers] Fix scheduling policy card icon --- src/content/docs/containers/index.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/index.mdx b/src/content/docs/containers/index.mdx index ac9727f47d3..7401ac4980e 100644 --- a/src/content/docs/containers/index.mdx +++ b/src/content/docs/containers/index.mdx @@ -224,9 +224,10 @@ Ship from your machine or Workers Builds, and confirm the deploy. - Choose whether image and instance configuration is managed centrally or from Durable Object code. + Choose whether image and instance configuration is managed centrally or from + Durable Object code. Date: Mon, 21 Sep 2026 11:16:18 -0400 Subject: [PATCH 04/73] [Containers] Use Durable Object Container API name --- src/content/changelog/containers/2026-09-03-snapshots.mdx | 2 +- src/content/docs/containers/get-started/index.mdx | 2 +- src/content/docs/containers/guides/snapshots.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/changelog/containers/2026-09-03-snapshots.mdx b/src/content/changelog/containers/2026-09-03-snapshots.mdx index ff8924d1388..2242f723411 100644 --- a/src/content/changelog/containers/2026-09-03-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-03-snapshots.mdx @@ -10,7 +10,7 @@ import { TypeScriptExample } from "~/components"; [Containers](/containers/) now support experimental snapshot APIs for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. -Use `snapshotContainer()` to capture the full container filesystem. The example uses the [low-level Durable Object container API](/durable-objects/api/container/). Create snapshots from a container that is already running: +Use `snapshotContainer()` to capture the full container filesystem. The example uses the [Durable Object Container API](/durable-objects/api/container/). Create snapshots from a container that is already running: diff --git a/src/content/docs/containers/get-started/index.mdx b/src/content/docs/containers/get-started/index.mdx index 1c9b1dac719..61ba08564bb 100644 --- a/src/content/docs/containers/get-started/index.mdx +++ b/src/content/docs/containers/get-started/index.mdx @@ -173,7 +173,7 @@ This defines basic configuration for the container: The `Container` class itself extends [`DurableObject`](/durable-objects/), so your subclass has access to the full Durable Object API. The Durable Object handles routing, lifecycle, and persistent state, while the container process runs your image inside a Linux VM. This means you can use [`this.ctx.storage`](/durable-objects/api/sqlite-storage-api/) to persist data that survives container restarts and resides close to the container itself. -For all properties and methods, refer to the [Container class API](/containers/api/container-class/). +For all properties and methods, refer to the [Container class API](/containers/api/container-class/) and the [Durable Object Container API](/containers/api/durable-object-container/). #### Routing to Containers diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index 2a2f8ca8037..44083f7ffb0 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -8,7 +8,7 @@ description: Persist container filesystem across restarts. import { TypeScriptExample } from "~/components"; -Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [low-level Durable Object container API](/durable-objects/api/container/). +Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [Durable Object Container API](/durable-objects/api/container/). ## Create a container snapshot From 1846040f2d5f72ddcb41135633d265c340948141 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:17:19 -0400 Subject: [PATCH 05/73] [Containers] Mark snapshots as public beta --- src/content/changelog/containers/2026-09-03-snapshots.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-03-snapshots.mdx b/src/content/changelog/containers/2026-09-03-snapshots.mdx index 2242f723411..db7b82e13f1 100644 --- a/src/content/changelog/containers/2026-09-03-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-03-snapshots.mdx @@ -1,6 +1,6 @@ --- title: Snapshot and restore Container state -description: Persist point-in-time container filesystem with experimental snapshot APIs. +description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers date: 2026-09-03 @@ -8,7 +8,7 @@ date: 2026-09-03 import { TypeScriptExample } from "~/components"; -[Containers](/containers/) now support experimental snapshot APIs for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. +[Containers](/containers/) now support snapshot APIs in public beta for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. Use `snapshotContainer()` to capture the full container filesystem. The example uses the [Durable Object Container API](/durable-objects/api/container/). Create snapshots from a container that is already running: From 2a7e652e4cdb0d79955f1904a11de376dbe5f92f Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:19:50 -0400 Subject: [PATCH 06/73] [Containers] Clarify snapshot immutability --- src/content/changelog/containers/2026-09-03-snapshots.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-03-snapshots.mdx b/src/content/changelog/containers/2026-09-03-snapshots.mdx index db7b82e13f1..492b9158066 100644 --- a/src/content/changelog/containers/2026-09-03-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-03-snapshots.mdx @@ -51,6 +51,6 @@ export class MyDurableObject extends DurableObject { -Snapshots are immutable. +Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. For more information, refer to [Snapshots](/containers/guides/snapshots/) and [Durable Object Container](/durable-objects/api/container/). From 9023441622d9c4c58c6779f4115c512c92746d7b Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:28:43 -0400 Subject: [PATCH 07/73] [Containers] Refine scheduling policy changelog --- .../2026-09-28-durable-object-scheduling-policy.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx index dae009399cd..cda6b063dc4 100644 --- a/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx @@ -1,5 +1,5 @@ --- -title: Configure Container image and instance size at runtime +title: New scheduling policy for Containers to configure image and instance from Durable Objects description: The durable_object scheduling policy gives each Durable Object control of Container configuration. products: - containers @@ -45,6 +45,6 @@ this.ctx.container.start({ -Durable Object-managed Container instances have independent lifecycles and do not participate in application-wide image rollouts. The existing `default` policy and its rollout behavior are unchanged. +Durable Object-managed Container instances have independent lifecycles and do not participate in application-wide image rollouts. For configuration, runtime sizing, snapshots, and update behavior, refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). From ad1cff21061bce4023427d905a8c933fcb162953 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:30:26 -0400 Subject: [PATCH 08/73] Publish Containers changelogs on September 30 --- ...icy.mdx => 2026-09-30-durable-object-scheduling-policy.mdx} | 3 ++- .../{2026-09-03-snapshots.mdx => 2026-09-30-snapshots.mdx} | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/content/changelog/containers/{2026-09-28-durable-object-scheduling-policy.mdx => 2026-09-30-durable-object-scheduling-policy.mdx} (96%) rename src/content/changelog/containers/{2026-09-03-snapshots.mdx => 2026-09-30-snapshots.mdx} (97%) diff --git a/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx similarity index 96% rename from src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx rename to src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index cda6b063dc4..229195a7405 100644 --- a/src/content/changelog/containers/2026-09-28-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -3,7 +3,8 @@ title: New scheduling policy for Containers to configure image and instance from description: The durable_object scheduling policy gives each Durable Object control of Container configuration. products: - containers -date: 2026-09-28 +date: 2026-09-30 +publish_future_dated_entry: true --- import { TypeScriptExample, WranglerConfig } from "~/components"; diff --git a/src/content/changelog/containers/2026-09-03-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx similarity index 97% rename from src/content/changelog/containers/2026-09-03-snapshots.mdx rename to src/content/changelog/containers/2026-09-30-snapshots.mdx index 492b9158066..05499f45161 100644 --- a/src/content/changelog/containers/2026-09-03-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -3,7 +3,8 @@ title: Snapshot and restore Container state description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers -date: 2026-09-03 +date: 2026-09-30 +publish_future_dated_entry: true --- import { TypeScriptExample } from "~/components"; From 03b773b44c0ea7b0b397bb66372a00597954af02 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:41:33 -0400 Subject: [PATCH 09/73] [Containers] Expand scheduling policy image guidance --- .../docs/containers/concepts/architecture.mdx | 6 +- .../containers/guides/image-management.mdx | 98 ++++++++++++++++--- 2 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/content/docs/containers/concepts/architecture.mdx b/src/content/docs/containers/concepts/architecture.mdx index 25699283ded..12620e4d1dc 100644 --- a/src/content/docs/containers/concepts/architecture.mdx +++ b/src/content/docs/containers/concepts/architecture.mdx @@ -12,9 +12,9 @@ products: How images and running Container instances update depends on the [scheduling policy](/containers/configuration/scheduling-policy/) for the application. -With the `default` policy, Wrangler uploads or resolves the application image. Cloudflare distributes that image across its network and prepares capacity for new instances. Changes to the image or instance type use a [rollout](/containers/configuration/rollouts/). +With the `durable_object` policy, Wrangler prepares the named images for the application. Durable Object code can access their immutable references and selects an image and instance size when it calls `ctx.container.start()`. When an image reference changes, the Durable Object decides whether to stop the running Container and start it with the new image or let it continue with the previous image. This application-controlled restart is how you roll out image changes with the `durable_object` policy. These instances do not participate in application-wide image rollouts. -With the `durable_object` policy, Wrangler prepares the named images for the application. Durable Object code can access their immutable references. The code selects an image and instance size when it calls `ctx.container.start()`. Running instances do not participate in application-wide image rollouts. +With the `default` policy, Wrangler uploads or resolves the application image. Cloudflare distributes that image across its network and prepares capacity for new instances. Changes to the image or instance type use a [rollout](/containers/configuration/rollouts/). Worker code goes live on deploy before any application-wide Container rollout finishes. Refer to [Deploy Containers](/containers/guides/deploy/). @@ -71,7 +71,7 @@ developers to address and route to specific container instances, run code when a ### Starting a Container -When a Durable Object requests a new Container instance, Cloudflare selects eligible capacity with the required image available. The `default` policy uses the application image and instance type from Wrangler configuration. The `durable_object` policy uses the `image` and `instance` options supplied to `ctx.container.start()`. +When a Durable Object requests a new Container instance, Cloudflare selects eligible capacity with the required image available. The `durable_object` policy uses the `image` and `instance` options supplied to `ctx.container.start()`. The `default` policy uses the application image and instance type from Wrangler configuration. :::note Durable Objects and their associated Container instances are not guaranteed to run in the diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index edd0e235459..50f955dfbf2 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -1,20 +1,90 @@ --- pcx_content_type: how-to title: Image Management -description: Learn how to use Cloudflare Registry, Docker Hub, and Amazon ECR images with Containers. +description: Configure and update Container images with the durable_object and default scheduling policies. sidebar: order: 4 products: - containers --- -import { WranglerConfig, PackageManagers, Steps } from "~/components"; +import { + PackageManagers, + Steps, + TypeScriptExample, + WranglerConfig, +} from "~/components"; -:::note -The `image` examples on this page apply to Container applications that use the [`default` scheduling policy](/containers/configuration/scheduling-policy/). For the `durable_object` policy, configure a named `images` map and select an image from `ctx.container.images` at runtime. A named `image` entry must be a digest-pinned reference in the Cloudflare managed registry; a named `dockerfile` entry can build from an external base image. -::: +Container applications manage images differently based on their [scheduling policy](/containers/configuration/scheduling-policy/). With the `durable_object` policy, Durable Object code selects a named 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 + +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: + + + +```jsonc +{ + "containers": [ + { + "class_name": "AgentComputer", + "scheduling_policy": "durable_object", + "images": { + "base": { + "dockerfile": "./container/Dockerfile", + "build_context": ".", + }, + "tools": { + "image": "registry.cloudflare.com//@sha256:", + }, + }, + }, + ], +} +``` + + + +Wrangler builds or resolves each named image and exposes its immutable reference through `ctx.container.images`. Select a reference when the Durable Object starts its Container: + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export class AgentComputer extends DurableObject { + startContainer() { + this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + }); + } +} +``` + + + +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](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). + +### 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. The corresponding value in `ctx.container.images` now refers to the updated image. + +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. + +### Use an external image + +A named `image` entry 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](#use-images-from-other-registries). Then, 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](/containers/configuration/rollouts/). -## Push images during `wrangler deploy` +### Push images during `wrangler deploy` When running `wrangler deploy`, if you set the `image` attribute in your [Wrangler configuration](/workers/wrangler/configuration/#containers) 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](/r2/). All authentication is handled automatically by @@ -45,7 +115,7 @@ Docker or a Docker-compatible CLI tool must be running for Wrangler to build and This is not necessary if you are using a pre-built image, as described below. ::: -## Use pre-built container images +### Use pre-built container images Containers support images from the Cloudflare managed registry at `registry.cloudflare.com`, [Docker Hub](https://hub.docker.com/), [Amazon ECR](https://aws.amazon.com/ecr/), and [Google Artifact Registry](https://cloud.google.com/artifact-registry). @@ -55,7 +125,7 @@ Cloudflare does not cache images pulled from Docker Hub, Amazon ECR, or Google A 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. ::: -### Use public Docker Hub images +#### 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. @@ -85,7 +155,7 @@ If Docker Hub credentials have been configured, those credentials are used to pu Official Docker Hub images use the `library` namespace. For example, use `docker.io/library/:` instead of `docker.io/:`. ::: -### Configure private registry credentials +#### Configure private registry credentials To use a private image from Docker Hub, Amazon ECR, or Google Artifact Registry, run [`wrangler containers registries configure`](/workers/wrangler/commands/containers/#containers-registries-configure) for the registry domain. @@ -93,7 +163,7 @@ Wrangler prompts for the secret and stores it in [Secrets Store](/secrets-store) 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 +#### Use private Docker Hub images Configure Docker Hub in Wrangler using these values: @@ -126,7 +196,7 @@ printf '%s' "$DOCKERHUB_PAT" | npx wrangler containers registries configure dock After you configure the registry, use the same fully qualified Docker Hub image reference shown above. -### Use private Amazon ECR images +#### Use private Amazon ECR images Configure Amazon ECR in Wrangler using these values: @@ -195,7 +265,7 @@ After you configure the registry, use the fully qualified Amazon ECR image refer -### Use private Google Artifact Registry images +#### Use private Google Artifact Registry images Configure Google Artifact Registry in Wrangler using these values: @@ -256,7 +326,7 @@ image = "-docker.pkg.dev///:" -### Use images from other registries +#### Use images from other registries If you want to use a pre-built image from another registry provider, first make sure it exists locally, then push it to the Cloudflare Registry: @@ -305,7 +375,7 @@ With `vite dev`, image references from external registries such as Docker Hub, A If you use a private Docker Hub, Amazon ECR, or Google Artifact Registry image in local development, authenticate to that registry locally, for example with `docker login`. ::: -## Push images with CI +### Push images with CI To use an image built in a continuous integration environment, install `wrangler` then build and push images using either `wrangler containers build` with the `--push` flag, or From eb544d0417e3556cfcd21583c6434ed81a391016 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:48:19 -0400 Subject: [PATCH 10/73] [Containers] Clarify external registry support --- src/content/docs/containers/guides/image-management.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 50f955dfbf2..8a4db44a8b7 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -76,7 +76,11 @@ Deploying an updated image map does not restart running Containers. A running Co ### Use an external image -A named `image` entry 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](#use-images-from-other-registries). Then, configure the resulting digest-pinned reference as a named image. +:::note +The `durable_object` scheduling policy does not support direct image references from external registries at this time. 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](#use-images-from-other-registries). Then, 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. From 7e65c315b44ba8e2c7e2fc8e3f8760a3f523f6d5 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Mon, 21 Sep 2026 11:50:03 -0400 Subject: [PATCH 11/73] Clarify scheduling policy field compatibility --- .../docs/workers/wrangler/configuration.mdx | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index d5e69dc9f34..eabe1e1d8e1 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1312,8 +1312,7 @@ You can define [Containers](/containers) to run alongside your Worker using the Each Container application has a [scheduling policy](/containers/configuration/scheduling-policy/) that determines whether image and instance configuration is managed centrally or supplied by Durable Object code at runtime. The policy is immutable after the application is created. :::note -You must also define a Durable Object to communicate with your Container via Workers. This Durable Object's -class name must match the `class_name` value in container configuration. +Each Container application must link to a Durable Object defined in the same Worker. Set `class_name` on the Container entry, or set `name` and reference that name from [`exports..container`](/durable-objects/reference/durable-objects-migrations/). Configure exactly one of these linkage directions. ::: The following options are available: @@ -1327,41 +1326,47 @@ The following options are available: - `images` - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. -- `class_name` +- `class_name` - The corresponding Durable Object class name. This will make this Durable Object a container-enabled Durable Object and allow each instance to control a container. Refer to the [Durable Object Container API](/containers/api/durable-object-container/) for details. -- `instance_type` + - Omit this field when the Container is linked by `name` from `exports..container`. +- `instance_type` - The instance type for the `default` policy. This determines the amount of memory, CPU, and disk given to the container instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, see the [instance types documentation](/containers/platform/limits/#instance-types). - For the `durable_object` policy, set the runtime `instance` option in `ctx.container.start()` instead. - To specify a custom instance type, see [here](#custom-instance-types). -- `max_instances` +- `max_instances` - The maximum number of concurrent container instances for the `default` policy. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. - Defaults to 20. - This value is only enforced when running in production on Cloudflare's network. This limit does not apply during local development, so you may run more instances than specified. - `name` - The name of your container. Used as an identifier. This will default to a combination of your Worker name, the class name, and your environment. -- `image_build_context` +- `image_build_context` - The build context of the application, by default it is the directory of `image`. -- `image_vars` +- `image_vars` - Build-time variables, equivalent to using `--build-arg` with `docker build`. If you want to provide environment variables to your container at _runtime_, you should [use secret bindings or `envVars` on the Container class](/containers/examples/env-vars-and-secrets/). -- `rollout_active_grace_period` +- `rollout_active_grace_period` - During a [rollout](/containers/configuration/rollouts/), minimum seconds a container instance must already have been connected to its Durable Object before it may be replaced. Defaults to `0`. Still applies with `--containers-rollout=immediate`. -- `rollout_step_percentage` +- `rollout_step_percentage` - Percentage of container instances to update at each [rollout](/containers/configuration/rollouts/) step. A single number uses that step size (`5`, `10`, `20`, `25`, `50`, or `100`). An array must contain ascending integer values from `10` through `100`, end in `100`, contain at most 10 entries, and contain no more entries than `max_instances`; its values are cumulative. Defaults to `100` if `max_instances` is omitted or less than `2`; otherwise defaults to `[10, 100]`. Override for one deploy with `--containers-rollout=immediate` (single 100% step; does not override grace period). -- `ssh` +- `observability` + - Overrides the root Worker observability configuration for this Container application. + - With the `durable_object` policy, set either `observability.enabled` or `observability.logs.enabled` to enable or disable application-wide Container logs. Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. +- `unsafe.configuration.experimental_flags` + - Experimental application flags. This is the only `unsafe` setting accepted with the `durable_object` policy. +- `ssh` - Configuration for SSH through Wrangler. Refer to [SSH](#ssh). -- `wrangler_ssh` +- `wrangler_ssh` - Deprecated alias for `ssh`. Still supported for backward compatibility. -- `authorized_keys` +- `authorized_keys` - Public keys that should be added to the Container's `authorized_keys` file. -- `constraints` +- `constraints` - Placement constraints for the container. Refer to [Containers placement](/containers/concepts/placement/) for details. -- `constraints.regions` +- `constraints.regions` - Limit container placement to specific geographic regions. Valid values: `"ENAM"`, `"WNAM"`, `"EEUR"`, `"WEUR"`, `"APAC"`, `"SAM"`, `"ME"`, `"OC"`, `"AFR"`. -- `constraints.jurisdiction` +- `constraints.jurisdiction` - Restrict containers to compliance boundaries. Valid values: `"eu"`, `"fedramp"`. @@ -1443,7 +1448,7 @@ For the `durable_object` policy, name one or more images and select one from Dur -Only policy-level fields such as `name`, `class_name`, `scheduling_policy`, and `images` apply to a Durable Object-managed entry. Configure its image and instance size in `ctx.container.start()` instead of setting `image`, `instance_type`, or rollout fields here. +A `durable_object` entry accepts only `name`, `class_name`, `scheduling_policy`, `images`, `observability`, and restricted `unsafe.configuration.experimental_flags`. Wrangler rejects every other Container application field for this policy. Configure the startup image or snapshot and instance size in `ctx.container.start()` instead of setting `image`, `instance_type`, or rollout fields here. ### Custom Instance Types From a83bf02f1c61e87d888aed1dfddd11127490e7ef Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 09:36:39 -0400 Subject: [PATCH 12/73] Document Container field policy compatibility --- .../docs/workers/wrangler/configuration.mdx | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index eabe1e1d8e1..baba3c2ef18 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1317,56 +1317,57 @@ Each Container application must link to a Durable Object defined in the same Wor The following options are available: -- `scheduling_policy` +- `scheduling_policy` - `"default"` uses the centrally configured application image, instance type, limits, and rollouts. This is the default when the field is omitted. - `"durable_object"` lets each Durable Object supply its Container image and instance size to `ctx.container.start()`. Refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). -- `image` +- `image` - The image to use for the container. This can either be a local path to a `Dockerfile`, in which case `wrangler deploy` will build and push the image, or it can be an image reference. Supported registries are the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry. For more information, refer to [Image Management](/containers/guides/image-management/). -- `images` +- `images` - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. -- `class_name` +- `class_name` - The corresponding Durable Object class name. This will make this Durable Object a container-enabled Durable Object and allow each instance to control a container. Refer to the [Durable Object Container API](/containers/api/durable-object-container/) for details. - Omit this field when the Container is linked by `name` from `exports..container`. -- `instance_type` +- `instance_type` - The instance type for the `default` policy. This determines the amount of memory, CPU, and disk given to the container instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, see the [instance types documentation](/containers/platform/limits/#instance-types). - For the `durable_object` policy, set the runtime `instance` option in `ctx.container.start()` instead. - To specify a custom instance type, see [here](#custom-instance-types). -- `max_instances` +- `max_instances` - The maximum number of concurrent container instances for the `default` policy. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. - Defaults to 20. - This value is only enforced when running in production on Cloudflare's network. This limit does not apply during local development, so you may run more instances than specified. -- `name` +- `name` - The name of your container. Used as an identifier. This will default to a combination of your Worker name, the class name, and your environment. -- `image_build_context` + - Required when `class_name` is omitted so that `exports..container` can reference the Container. +- `image_build_context` - The build context of the application, by default it is the directory of `image`. -- `image_vars` +- `image_vars` - Build-time variables, equivalent to using `--build-arg` with `docker build`. If you want to provide environment variables to your container at _runtime_, you should [use secret bindings or `envVars` on the Container class](/containers/examples/env-vars-and-secrets/). -- `rollout_active_grace_period` +- `rollout_active_grace_period` - During a [rollout](/containers/configuration/rollouts/), minimum seconds a container instance must already have been connected to its Durable Object before it may be replaced. Defaults to `0`. Still applies with `--containers-rollout=immediate`. -- `rollout_step_percentage` +- `rollout_step_percentage` - Percentage of container instances to update at each [rollout](/containers/configuration/rollouts/) step. A single number uses that step size (`5`, `10`, `20`, `25`, `50`, or `100`). An array must contain ascending integer values from `10` through `100`, end in `100`, contain at most 10 entries, and contain no more entries than `max_instances`; its values are cumulative. Defaults to `100` if `max_instances` is omitted or less than `2`; otherwise defaults to `[10, 100]`. Override for one deploy with `--containers-rollout=immediate` (single 100% step; does not override grace period). -- `observability` +- `observability` - Overrides the root Worker observability configuration for this Container application. - With the `durable_object` policy, set either `observability.enabled` or `observability.logs.enabled` to enable or disable application-wide Container logs. Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. -- `unsafe.configuration.experimental_flags` +- `unsafe.configuration.experimental_flags` - Experimental application flags. This is the only `unsafe` setting accepted with the `durable_object` policy. -- `ssh` +- `ssh` - Configuration for SSH through Wrangler. Refer to [SSH](#ssh). -- `wrangler_ssh` +- `wrangler_ssh` - Deprecated alias for `ssh`. Still supported for backward compatibility. -- `authorized_keys` +- `authorized_keys` - Public keys that should be added to the Container's `authorized_keys` file. -- `constraints` +- `constraints` - Placement constraints for the container. Refer to [Containers placement](/containers/concepts/placement/) for details. -- `constraints.regions` +- `constraints.regions` - Limit container placement to specific geographic regions. Valid values: `"ENAM"`, `"WNAM"`, `"EEUR"`, `"WEUR"`, `"APAC"`, `"SAM"`, `"ME"`, `"OC"`, `"AFR"`. -- `constraints.jurisdiction` +- `constraints.jurisdiction` - Restrict containers to compliance boundaries. Valid values: `"eu"`, `"fedramp"`. From 810c4832d876295ff1b07a5fdb78a0c96d87ab51 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 09:39:20 -0400 Subject: [PATCH 13/73] Split Container fields by scheduling policy --- .../docs/workers/wrangler/configuration.mdx | 93 +++++++++++-------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index baba3c2ef18..e05f0a08643 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1315,59 +1315,55 @@ Each Container application has a [scheduling policy](/containers/configuration/s Each Container application must link to a Durable Object defined in the same Worker. Set `class_name` on the Container entry, or set `name` and reference that name from [`exports..container`](/durable-objects/reference/durable-objects-migrations/). Configure exactly one of these linkage directions. ::: +### `default` scheduling policy + +The `default` policy stores the image and instance configuration on the Container application and manages deployments as rollouts. It is used when `scheduling_policy` is omitted or set to `"default"`. + The following options are available: -- `scheduling_policy` - - `"default"` uses the centrally configured application image, instance type, limits, and rollouts. This is the default when the field is omitted. - - `"durable_object"` lets each Durable Object supply its Container image and instance size to `ctx.container.start()`. Refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). -- `image` +- `scheduling_policy` + - Set to `"default"`, or omit this field. +- `image` - The image to use for the container. This can either be a local path to a `Dockerfile`, in which case `wrangler deploy` will build and push the image, or it can be an image reference. Supported registries are the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry. For more information, refer to [Image Management](/containers/guides/image-management/). -- `images` - - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. - - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. -- `class_name` +- `class_name` - The corresponding Durable Object class name. This will make this Durable Object a container-enabled Durable Object and allow each instance to control a container. Refer to the [Durable Object Container API](/containers/api/durable-object-container/) for details. - Omit this field when the Container is linked by `name` from `exports..container`. -- `instance_type` - - The instance type for the `default` policy. This determines the amount of memory, CPU, and disk given to the container - instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, - see the [instance types documentation](/containers/platform/limits/#instance-types). - - For the `durable_object` policy, set the runtime `instance` option in `ctx.container.start()` instead. - - To specify a custom instance type, see [here](#custom-instance-types). -- `max_instances` - - The maximum number of concurrent container instances for the `default` policy. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. - - Defaults to 20. - - This value is only enforced when running in production on Cloudflare's network. This limit does not apply during local development, so you may run more instances than specified. -- `name` +- `name` - The name of your container. Used as an identifier. This will default to a combination of your Worker name, the class name, and your environment. - Required when `class_name` is omitted so that `exports..container` can reference the Container. -- `image_build_context` +- `instance_type` + - The instance type determines the amount of memory, CPU, and disk given to the container instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, see the [instance types documentation](/containers/platform/limits/#instance-types). + - To specify a custom instance type, see [Custom instance types](#custom-instance-types). +- `max_instances` + - The maximum number of concurrent container instances. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. + - Defaults to 20. + - This value is only enforced when running in production on Cloudflare's network. This limit does not apply during local development, so you may run more instances than specified. +- `image_build_context` - The build context of the application, by default it is the directory of `image`. -- `image_vars` +- `image_vars` - Build-time variables, equivalent to using `--build-arg` with `docker build`. If you want to provide environment variables to your container at _runtime_, you should [use secret bindings or `envVars` on the Container class](/containers/examples/env-vars-and-secrets/). -- `rollout_active_grace_period` +- `rollout_active_grace_period` - During a [rollout](/containers/configuration/rollouts/), minimum seconds a container instance must already have been connected to its Durable Object before it may be replaced. Defaults to `0`. Still applies with `--containers-rollout=immediate`. -- `rollout_step_percentage` +- `rollout_step_percentage` - Percentage of container instances to update at each [rollout](/containers/configuration/rollouts/) step. A single number uses that step size (`5`, `10`, `20`, `25`, `50`, or `100`). An array must contain ascending integer values from `10` through `100`, end in `100`, contain at most 10 entries, and contain no more entries than `max_instances`; its values are cumulative. Defaults to `100` if `max_instances` is omitted or less than `2`; otherwise defaults to `[10, 100]`. Override for one deploy with `--containers-rollout=immediate` (single 100% step; does not override grace period). -- `observability` +- `observability` - Overrides the root Worker observability configuration for this Container application. - - With the `durable_object` policy, set either `observability.enabled` or `observability.logs.enabled` to enable or disable application-wide Container logs. Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. -- `unsafe.configuration.experimental_flags` - - Experimental application flags. This is the only `unsafe` setting accepted with the `durable_object` policy. -- `ssh` +- `unsafe.configuration.experimental_flags` + - Experimental application flags. +- `ssh` - Configuration for SSH through Wrangler. Refer to [SSH](#ssh). -- `wrangler_ssh` +- `wrangler_ssh` - Deprecated alias for `ssh`. Still supported for backward compatibility. -- `authorized_keys` +- `authorized_keys` - Public keys that should be added to the Container's `authorized_keys` file. -- `constraints` +- `constraints` - Placement constraints for the container. Refer to [Containers placement](/containers/concepts/placement/) for details. -- `constraints.regions` +- `constraints.regions` - Limit container placement to specific geographic regions. Valid values: `"ENAM"`, `"WNAM"`, `"EEUR"`, `"WEUR"`, `"APAC"`, `"SAM"`, `"ME"`, `"OC"`, `"AFR"`. -- `constraints.jurisdiction` +- `constraints.jurisdiction` - Restrict containers to compliance boundaries. Valid values: `"eu"`, `"fedramp"`. @@ -1409,7 +1405,30 @@ The following options are available: -For the `durable_object` policy, name one or more images and select one from Durable Object code when the Container starts: +### `durable_object` scheduling policy + +The `durable_object` policy lets each Durable Object supply its Container image or snapshot and instance size to `ctx.container.start()`. Set `scheduling_policy` to `"durable_object"` explicitly. + +A `durable_object` entry accepts only the following options. Wrangler rejects every other Container application field for this policy. + +- `scheduling_policy` + - Must be set to `"durable_object"`. +- `images` + - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. + - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. +- `class_name` + - The corresponding Durable Object class name. + - Omit this field when the Container is linked by `name` from `exports..container`. +- `name` + - The name of the Container application. + - Required when `class_name` is omitted so that `exports..container` can reference the Container. +- `observability` + - Set either `observability.enabled` or `observability.logs.enabled` to enable or disable application-wide Container logs. + - Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. +- `unsafe.configuration.experimental_flags` + - Experimental application flags. This is the only `unsafe` setting accepted with the `durable_object` policy. + +Name one or more images and select one from Durable Object code when the Container starts: @@ -1449,11 +1468,11 @@ For the `durable_object` policy, name one or more images and select one from Dur -A `durable_object` entry accepts only `name`, `class_name`, `scheduling_policy`, `images`, `observability`, and restricted `unsafe.configuration.experimental_flags`. Wrangler rejects every other Container application field for this policy. Configure the startup image or snapshot and instance size in `ctx.container.start()` instead of setting `image`, `instance_type`, or rollout fields here. +Configure the startup image or snapshot and instance size in `ctx.container.start()`. Fields from the `default` policy, including `image`, `instance_type`, `max_instances`, rollout settings, SSH settings, and placement constraints, are not supported. ### Custom Instance Types -In place of the [named instance types](/containers/platform/limits/#instance-types), you can set a custom instance type by individually configuring vCPU, memory, and disk. +Custom instance types only apply to the `default` scheduling policy. In place of the [named instance types](/containers/platform/limits/#instance-types), you can set a custom instance type by individually configuring vCPU, memory, and disk. See the [limits documentation](/containers/platform/limits/#custom-instance-types) for constraints on custom instance types. The following options are available: @@ -1488,7 +1507,7 @@ The following options are available: ### SSH -Configuration for SSH access to a Container instance through Wrangler. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). +SSH configuration only applies to the `default` scheduling policy. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). The following options are available: From ad09a49eec95340de417d5d3649a4cae27f4f111 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 09:47:37 -0400 Subject: [PATCH 14/73] Clarify snapshot image compatibility --- src/content/docs/containers/guides/snapshots.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index 44083f7ffb0..a047212e52e 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -14,6 +14,10 @@ Snapshots let you save point-in-time filesystem state from a running [Container] Use `snapshotContainer()` to capture the full container filesystem. Snapshots are immutable. If you restore a snapshot and then change files, create a new snapshot to persist those changes. +:::caution[Snapshots are bound to an image] +Snapshots capture the full Container filesystem rather than an image-independent data layer. A snapshot is bound to the exact image it was created from and cannot be restored with a different or updated image. After changing the image, create a new snapshot from a Container running that image. +::: + The returned snapshot handle is a plain data object. You can store it and restore it later, including from another Durable Object: From e5c0b2c99d8e70ae4956fdd35398a1a3b8d88f16 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 09:51:29 -0400 Subject: [PATCH 15/73] Use standard snapshot compatibility terminology --- src/content/docs/containers/guides/snapshots.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index a047212e52e..72b05829153 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -14,8 +14,8 @@ Snapshots let you save point-in-time filesystem state from a running [Container] Use `snapshotContainer()` to capture the full container filesystem. Snapshots are immutable. If you restore a snapshot and then change files, create a new snapshot to persist those changes. -:::caution[Snapshots are bound to an image] -Snapshots capture the full Container filesystem rather than an image-independent data layer. A snapshot is bound to the exact image it was created from and cannot be restored with a different or updated image. After changing the image, create a new snapshot from a Container running that image. +:::caution[Snapshot image compatibility] +Snapshots capture the Container's complete filesystem state, but not its memory or running processes. A snapshot is tied to the Container image version it was created from and is not portable to a different image. After updating the image, create a new snapshot from a Container running that image. ::: The returned snapshot handle is a plain data object. You can store it and restore it later, including from another Durable Object: From a524175fd8e0792c72c6a50e6f761d1e31c6fbbb Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 11:19:51 -0400 Subject: [PATCH 16/73] Document Cloudflare managed Container image --- .../docs/containers/guides/image-management.mdx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 8a4db44a8b7..8488f48b0d8 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -17,6 +17,16 @@ import { Container applications manage images differently based on their [scheduling policy](/containers/configuration/scheduling-policy/). With the `durable_object` policy, Durable Object code selects a named image each time it starts a Container. With the `default` policy, Wrangler configuration sets one image for the application. +## Cloudflare-managed image + +Cloudflare provides the following managed image: + +| Managed image | Source image | Contents | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| `cloudflare/debian-trixie` | [`node:24.20.0-trixie-slim`](https://hub.docker.com/layers/library/node/24.20.0-trixie-slim/images/sha256-a747ad80c8a161b650d79a6da9c422005b91148b18b8d2c669eb5a0b7c07e600) 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. + ## Use images with the `durable_object` scheduling policy 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. From 4436a55618e9116ba7fd142e1413c1b25b294bde Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Wed, 23 Sep 2026 11:26:58 -0400 Subject: [PATCH 17/73] Scope managed Container image to Durable Objects --- .../containers/guides/image-management.mdx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 8488f48b0d8..2797456f9f6 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -15,19 +15,31 @@ import { WranglerConfig, } from "~/components"; -Container applications manage images differently based on their [scheduling policy](/containers/configuration/scheduling-policy/). With the `durable_object` policy, Durable Object code selects a named image each time it starts a Container. With the `default` policy, Wrangler configuration sets one image for the application. +Container applications manage images differently based on their [scheduling policy](/containers/configuration/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. -## Cloudflare-managed image +## Use images with the `durable_object` scheduling policy + +### Use the Cloudflare-managed image -Cloudflare provides the following 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`](https://hub.docker.com/layers/library/node/24.20.0-trixie-slim/images/sha256-a747ad80c8a161b650d79a6da9c422005b91148b18b8d2c669eb5a0b7c07e600) 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. +`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: -## Use images with the `durable_object` scheduling policy + + +```ts +this.ctx.container.start({ + image: "cloudflare/debian-trixie", +}); +``` + + + +### 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. From 7a1bd295af0242069ee2874c80ac818ceecb44cf Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Thu, 24 Sep 2026 20:31:58 -0400 Subject: [PATCH 18/73] Document scheduling policy migration --- .../index.mdx} | 10 +- .../scheduling-policy/move-from-default.mdx | 193 ++++++++++++++++++ 2 files changed, 198 insertions(+), 5 deletions(-) rename src/content/docs/containers/configuration/{scheduling-policy.mdx => scheduling-policy/index.mdx} (82%) create mode 100644 src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx diff --git a/src/content/docs/containers/configuration/scheduling-policy.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx similarity index 82% rename from src/content/docs/containers/configuration/scheduling-policy.mdx rename to src/content/docs/containers/configuration/scheduling-policy/index.mdx index db3913c70be..704246c5729 100644 --- a/src/content/docs/containers/configuration/scheduling-policy.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -12,12 +12,12 @@ import { TypeScriptExample, WranglerConfig } from "~/components"; A scheduling policy determines where you configure a Container image and instance size. It also determines how image updates apply. Choose the policy when you create the Container application. -| Policy | Configure image and instance size | Image updates | Best for | -| - | - | - | - | -| `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | -| `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | +| Policy | Configure image and instance size | Image updates | Best for | +| ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | +| `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | -The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. +The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Move from the default scheduling policy](/containers/configuration/scheduling-policy/move-from-default/). :::note The `durable_object` scheduling policy is in public beta. diff --git a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx new file mode 100644 index 00000000000..2668c2a84bf --- /dev/null +++ b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx @@ -0,0 +1,193 @@ +--- +pcx_content_type: how-to +title: Move from the default scheduling policy +description: Replace a Container application that uses the default scheduling policy with a Durable Object-managed application. +sidebar: + order: 1 +products: + - containers +--- + +import { + PackageManagers, + Steps, + TypeScriptExample, + WranglerConfig, +} from "~/components"; + +You cannot change the scheduling policy of an existing Container application. To move from the `default` policy to the `durable_object` policy, create a replacement Container application and cut traffic over to it. + +The replacement application must use a new Durable Object class and namespace. The old and replacement applications cannot attach to the same Durable Object namespace. + +:::caution + +This process does not transfer existing Container instances, their filesystems, or Durable Object storage. The `default` scheduling policy does not support snapshots, so you cannot use a Container snapshot to transfer its filesystem. + +If the existing Durable Objects contain data, design an application-specific transfer process before continuing. + +::: + +## Configuration changes + +Map the existing application configuration to its `durable_object` equivalent: + +| `default` policy | `durable_object` policy | +| -------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `image` | A named `images` entry, selected with `ctx.container.start()` | +| `image_build_context` | `build_context` on the named image | +| `image_vars` | `build_vars` on the named image | +| `instance_type` | The `instance` option in `ctx.container.start()` | +| Application-wide image rollouts | Application code that stops and starts each Container | +| `observability` | Keep in Wrangler configuration, subject to `durable_object` restrictions | +| `unsafe.configuration.experimental_flags` | Keep in Wrangler configuration | +| `max_instances`, placement constraints, rollout settings, and SSH settings | Not supported on the replacement application | + +For the complete field compatibility list, refer to [Wrangler configuration](/workers/wrangler/configuration/#containers). + +## Move the application + + + +1. **Create a replacement Durable Object class.** + + Add a new SQLite-backed Durable Object class and binding. Keep the existing class and binding so that you can route traffic back to them. + + Use the Durable Object lifecycle configuration already used by your Worker. If the Worker uses the legacy `migrations` array, append a migration with the replacement class in `new_sqlite_classes`. If it uses `exports`, declare the replacement class there. Do not switch between `migrations` and `exports` as part of this process. + +2. **Add a replacement Container application.** + + Keep the existing application and add a differently named application with the `durable_object` policy. The following example uses the legacy `migrations` array: + + + + ```jsonc + { + "name": "sandbox-worker", + "main": "src/index.ts", + "compatibility_date": "$today", + "containers": [ + { + "name": "sandbox-default", + "class_name": "LegacySandbox", + "scheduling_policy": "default", + "image": "./container/Dockerfile", + "instance_type": "standard-2", + "max_instances": 10, + }, + { + "name": "sandbox-durable-object", + "class_name": "DurableSandbox", + "scheduling_policy": "durable_object", + "images": { + "base": { + "dockerfile": "./container/Dockerfile", + }, + }, + }, + ], + "durable_objects": { + "bindings": [ + { + "name": "LEGACY_SANDBOX", + "class_name": "LegacySandbox", + }, + { + "name": "DURABLE_SANDBOX", + "class_name": "DurableSandbox", + }, + ], + }, + "migrations": [ + { + "tag": "v1", + "new_sqlite_classes": ["LegacySandbox"], + }, + { + "tag": "v2", + "new_sqlite_classes": ["DurableSandbox"], + }, + ], + } + ``` + + + +3. **Move startup configuration into the replacement class.** + + Select the image and instance size when the replacement Durable Object starts its Container: + + + + ```ts + import { DurableObject } from "cloudflare:workers"; + + export class DurableSandbox extends DurableObject { + startContainer() { + if (this.ctx.container.running) { + return; + } + + this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + }); + } + } + ``` + + + + Move other supported startup settings, such as `env`, `entrypoint`, and `enableInternet`, into the same call. Add an application-specific readiness check before sending traffic to the Container. + +4. **Deploy and validate the replacement application.** + + Deploy both applications: + + + + Start a replacement Container without changing production routing. Confirm that the image, instance size, environment, entrypoint, network access, and readiness behavior match the existing application. + +5. **Cut traffic over to the replacement namespace.** + + Update the Worker routing logic to resolve Container IDs through the replacement Durable Object binding. New Durable Object IDs refer to the replacement namespace and do not access storage from the old namespace. + + For example, you can use a feature flag to select the binding while keeping the same logical name: + + ```ts + const binding = useReplacement + ? env.DURABLE_SANDBOX + : env.LEGACY_SANDBOX; + const sandbox = binding.getByName(sandboxName); + ``` + + If Durable Object state must move, complete the application-specific transfer before routing all traffic to the replacement namespace. + +6. **Observe the replacement application.** + + Keep the old application, class, and binding during the observation period. To roll back, route traffic to the old Durable Object binding again. + + Writes made after cutover stay in the replacement namespace. If the application accepts writes, plan how to reconcile that data before rolling back. + +7. **Delete the old Container application.** + + After the rollback period, remove the old Container entry and routing code from the Worker configuration. Deploy the updated Worker. Keep the old Durable Object class and binding until you no longer need its stored data. + + Removing the entry from Wrangler configuration does not delete the existing Container application. List the applications and copy the old application ID: + + + + Delete the old application: + + + + This command deletes the application and its Container instances. + + Delete the old Durable Object class only when its stored data is no longer needed. Deleting a Durable Object class permanently deletes its namespace and stored data. Refer to [Durable Object class exports](/durable-objects/reference/durable-objects-migrations/) or [Durable Object class migrations (legacy)](/durable-objects/reference/durable-object-class-migrations-legacy/) for the applicable cleanup process. + + + +## Related resources + +- [Scheduling Policies](/containers/configuration/scheduling-policy/) +- [Image Management](/containers/guides/image-management/) +- [Durable Object Container API](/durable-objects/api/container/) From eaede2d89604c2cec614fa9970b49543a8b30447 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Thu, 24 Sep 2026 20:54:17 -0400 Subject: [PATCH 19/73] Rename scheduling policy migration guide --- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- .../configuration/scheduling-policy/move-from-default.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 704246c5729..faade626284 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -17,7 +17,7 @@ A scheduling policy determines where you configure a Container image and instanc | `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | | `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | -The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Move from the default scheduling policy](/containers/configuration/scheduling-policy/move-from-default/). +The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Move to the Durable Object scheduling policy](/containers/configuration/scheduling-policy/move-from-default/). :::note The `durable_object` scheduling policy is in public beta. diff --git a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx index 2668c2a84bf..357b0e1a4c3 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx @@ -1,6 +1,6 @@ --- pcx_content_type: how-to -title: Move from the default scheduling policy +title: Move to the Durable Object scheduling policy description: Replace a Container application that uses the default scheduling policy with a Durable Object-managed application. sidebar: order: 1 From 859cbefdedd0b9c6ec6742c53b5ee8c5c2276543 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Thu, 24 Sep 2026 20:55:17 -0400 Subject: [PATCH 20/73] Clarify snapshot scheduling policy requirement --- src/content/docs/containers/guides/snapshots.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index 72b05829153..d236fe232f1 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -3,13 +3,17 @@ title: Use snapshots pcx_content_type: how-to sidebar: order: 7 -description: Persist container filesystem across restarts. +description: Save and restore Container filesystems with the Durable Object scheduling policy. --- import { TypeScriptExample } from "~/components"; Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [Durable Object Container API](/durable-objects/api/container/). +:::note[Scheduling policy requirement] +Snapshots are only supported by Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Applications that use the `default` scheduling policy cannot create or restore snapshots. +::: + ## Create a container snapshot Use `snapshotContainer()` to capture the full container filesystem. Snapshots are immutable. If you restore a snapshot and then change files, create a new snapshot to persist those changes. @@ -71,5 +75,6 @@ You cannot set a custom time-to-live yet. ## Related resources +- [Scheduling Policies](/containers/configuration/scheduling-policy/) - Choose how Container instances are configured and updated - [Durable Object Container](/durable-objects/api/container/) - Full `ctx.container` API reference - [Lifecycle of a Container](/containers/concepts/architecture/) - Understand startup, sleep, and shutdown behavior From f917823db37247d29a996eaacb42ec0bd59dbd8f Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:04:24 -0400 Subject: [PATCH 21/73] Update src/content/docs/workers/wrangler/configuration.mdx Co-authored-by: Thomas Lefebvre --- src/content/docs/workers/wrangler/configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index e05f0a08643..61285ec1b83 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1468,7 +1468,7 @@ Name one or more images and select one from Durable Object code when the Contain -Configure the startup image or snapshot and instance size in `ctx.container.start()`. Fields from the `default` policy, including `image`, `instance_type`, `max_instances`, rollout settings, SSH settings, and placement constraints, are not supported. +Configure the startup image or snapshot and instance size in `ctx.container.start()`. Fields from the `default` policy, including `image`, `instance_type`, `max_instances`, rollout settings, and placement constraints, are not supported. ### Custom Instance Types From 53ed8efe82e066adebebb5462b70729df4d84d2c Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:04:38 -0400 Subject: [PATCH 22/73] Update src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx Co-authored-by: Thomas Lefebvre --- .../configuration/scheduling-policy/move-from-default.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx index 357b0e1a4c3..dff49eebf2b 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx @@ -130,6 +130,7 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo this.ctx.container.start({ image: this.ctx.container.images.base, instance: "standard-2", + enableInternet: false, }); } } From c1f64b62b1b3c660e012b4c3e6046e40b3aed3cc Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:04:54 -0400 Subject: [PATCH 23/73] Update src/content/docs/containers/guides/image-management.mdx Co-authored-by: Thomas Lefebvre --- src/content/docs/containers/guides/image-management.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 2797456f9f6..a1fcbf16087 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -34,6 +34,7 @@ The `cloudflare/debian-trixie` managed image is available only with the `durable ```ts this.ctx.container.start({ image: "cloudflare/debian-trixie", + enableInternet: false, }); ``` From 7bdd9bf0c74ccdf2a332dfcdf2fc48d0ef7b9756 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:05:08 -0400 Subject: [PATCH 24/73] Update src/content/docs/containers/guides/image-management.mdx Co-authored-by: Thomas Lefebvre --- src/content/docs/containers/guides/image-management.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index a1fcbf16087..e0822bbc775 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -82,6 +82,7 @@ export class AgentComputer extends DurableObject { this.ctx.container.start({ image: this.ctx.container.images.base, instance: "standard-2", + enableInternet: false, }); } } From 5528c946774630c8af6be76c8c16d082982137e3 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:05:19 -0400 Subject: [PATCH 25/73] Update src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx Co-authored-by: Thomas Lefebvre --- .../containers/2026-09-30-durable-object-scheduling-policy.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index 229195a7405..b9efebda9b0 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -40,6 +40,7 @@ Wrangler prepares each image and exposes its immutable reference through `ctx.co ```ts this.ctx.container.start({ image: this.ctx.container.images.base, + enableInternet: false, instance: "standard-2", }); ``` From f6ded93c4c397a37d4941e3054165a717be67ae8 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:05:29 -0400 Subject: [PATCH 26/73] Update src/content/docs/containers/configuration/scheduling-policy/index.mdx Co-authored-by: Thomas Lefebvre --- .../docs/containers/configuration/scheduling-policy/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index faade626284..be4e66d4fce 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -141,6 +141,7 @@ If you omit `instance`, the Container uses `lite`. You can also supply a custom ```ts this.ctx.container.start({ image: this.ctx.container.images.base, + enableInternet: false, instance: { vcpu: 1, memoryMib: 4096, From 9322266fe98271c7c72c292754ac1536c96b4658 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:05:39 -0400 Subject: [PATCH 27/73] Update src/content/changelog/containers/2026-09-30-snapshots.mdx Co-authored-by: Thomas Lefebvre --- src/content/changelog/containers/2026-09-30-snapshots.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 05499f45161..323e5a69876 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -45,7 +45,7 @@ export class MyDurableObject extends DurableObject { return; } - this.ctx.container.start({ containerSnapshot }); + this.ctx.container.start({ containerSnapshot, enableInternet: false }); } } ``` From 2e0229a29b962f455c410014441bb7a733e7e065 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:05:48 -0400 Subject: [PATCH 28/73] Update src/content/docs/containers/guides/snapshots.mdx Co-authored-by: Thomas Lefebvre --- src/content/docs/containers/guides/snapshots.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index d236fe232f1..3e6746b873c 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -60,7 +60,7 @@ export class MyDurableObject extends DurableObject { return; } - this.ctx.container.start({ containerSnapshot }); + this.ctx.container.start({ containerSnapshot, enableInternet: false }); } } ``` From 52451fc2c80d75739576414e9faeda0fdeb4bf93 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 17:47:05 -0400 Subject: [PATCH 29/73] Update src/content/docs/workers/wrangler/configuration.mdx Co-authored-by: Thomas Lefebvre --- src/content/docs/workers/wrangler/configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 61285ec1b83..33a05b897e1 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1507,7 +1507,7 @@ The following options are available: ### SSH -SSH configuration only applies to the `default` scheduling policy. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). +SSH configuration applies to both the `default` and `durable_object` scheduling policies. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). The following options are available: From 5e490077a31f0c7093a303e4bf37f682618369b2 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:33:55 -0400 Subject: [PATCH 30/73] Resolve rebase against production --- .../containers/2026-09-30-snapshots.mdx | 4 +- .../api/durable-object-container.mdx | 75 ++++++++++++++++++- .../docs/containers/configuration/index.mdx | 2 +- .../configuration/scheduling-policy/index.mdx | 6 +- .../scheduling-policy/move-from-default.mdx | 2 +- .../containers/guides/image-management.mdx | 36 +++++++++ .../docs/containers/guides/snapshots.mdx | 4 +- 7 files changed, 118 insertions(+), 11 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 323e5a69876..134b38a8427 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -11,7 +11,7 @@ import { TypeScriptExample } from "~/components"; [Containers](/containers/) now support snapshot APIs in public beta for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. -Use `snapshotContainer()` to capture the full container filesystem. The example uses the [Durable Object Container API](/durable-objects/api/container/). Create snapshots from a container that is already running: +Use `snapshotContainer()` to capture the full container filesystem. The example uses the [Durable Object Container API](/containers/api/durable-object-container/). Create snapshots from a container that is already running: @@ -54,4 +54,4 @@ export class MyDurableObject extends DurableObject { Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. -For more information, refer to [Snapshots](/containers/guides/snapshots/) and [Durable Object Container](/durable-objects/api/container/). +For more information, refer to [Snapshots](/containers/guides/snapshots/) and the [Durable Object Container API](/containers/api/durable-object-container/). diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 5546b1c9a90..f566640a502 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -54,6 +54,20 @@ export class MyDurableObject extends DurableObject { ## Attributes +### `images` + +`images` is a read-only map of named images configured for an application that uses the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Each value is a digest-pinned image reference prepared by Wrangler. + + + +```ts +const image = this.ctx.container.images.base; +``` + + + +Pass a value from this map as the `image` option to [`start()`](#start). + ### `running` `running` is `true` when the container is running. It does not confirm that the container is ready to accept requests. @@ -68,21 +82,52 @@ this.ctx.container.running; `start()` boots a container. It returns before the container is ready to accept requests. Confirm readiness before sending traffic. -```js -this.ctx.container.start(); + + +```ts +this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + enableInternet: true, +}); ``` + + #### Parameters - `options` (`object`, optional): Common container startup options: - `env` (`Record`, optional): Environment variables to pass to the container. - `entrypoint` (`string[]`, optional): Command and arguments to run in the container. - `enableInternet` (`boolean`, required): Whether to allow outbound Internet access. Required when you pass `options`. + - `image` (`string`, optional): Image reference to start. For an application that uses the `durable_object` scheduling policy, pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). Omit this option when restoring a snapshot. + - `instance` (`string | object`, optional): Instance size for an application that uses the `durable_object` scheduling policy. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. + - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional): Full container snapshot to restore before startup. You cannot pass both `containerSnapshot` and `image`. #### Return values - `void`: No return value. +### `inspect` + +`inspect()` returns the image and labels for a running container. It returns `null` when no container is running. + + + +```ts +const containerInfo = await this.ctx.container.inspect(); +``` + + + +#### Parameters + +- None. + +#### Return values + +- `Promise`: Resolves with the running container information or `null`. + ### `exec` `exec()` starts another process inside an already-running container. It does not start a stopped container. @@ -170,6 +215,31 @@ With `stderr: "combined"`, `stderr` is `null` on `ExecProcess` and an empty `Arr For task-oriented examples, refer to [Execute commands](/containers/guides/execute-commands/). +### `snapshotContainer` + +`snapshotContainer()` creates a point-in-time snapshot of the running container filesystem. + + + +```ts +const snapshot = await this.ctx.container.snapshotContainer({ + name: "before-upgrade", +}); +``` + + + +#### Parameters + +- `options` (`ContainerSnapshotOptions`): Snapshot configuration: + - `name` (`string`, optional): Human-readable name for the snapshot. + +#### Return values + +- `Promise`: Resolves with a snapshot containing `id`, `size`, and an optional `name`. + +Container snapshots are immutable. Snapshot handles currently have an implicit 30-day time-to-live that refreshes when you restore them. For the complete save and restore flow, refer to [Use snapshots](/containers/guides/snapshots/). + ### `destroy` `destroy()` stops the container and can include an optional reason for the operation. @@ -374,3 +444,4 @@ await this.ctx.container.interceptOutboundHttps("*", worker); - [Get started with Containers](/containers/get-started/): Deploy your first container. - [SQLite storage API](/durable-objects/api/sqlite-storage-api/): Persist state across container restarts. - [Durable Objects](/durable-objects/): The underlying platform that powers Containers. +- [Snapshots](/containers/guides/snapshots/): Save and restore container filesystems. diff --git a/src/content/docs/containers/configuration/index.mdx b/src/content/docs/containers/configuration/index.mdx index 4b06ca82c16..1426373687f 100644 --- a/src/content/docs/containers/configuration/index.mdx +++ b/src/content/docs/containers/configuration/index.mdx @@ -1,7 +1,7 @@ --- pcx_content_type: navigation title: Configuration -description: Choose a scheduling policy, connect Containers to Workers and bindings, set environment variables, tune scaling and routing, and manage rollouts. +description: Choose a scheduling policy, configure Containers in Wrangler, connect bindings, set environment variables, tune scaling, and manage rollouts. sidebar: order: 5 group: diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index be4e66d4fce..2ee210615be 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -114,7 +114,7 @@ export class AgentComputer extends DurableObject { -`ctx.container.start()` initiates startup and returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic or calling [`exec()`](/durable-objects/api/container/#exec). +`ctx.container.start()` initiates startup and returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic or calling [`exec()`](/containers/api/durable-object-container/#exec). ### Configure named images @@ -128,7 +128,7 @@ The image map is uploaded with the Worker version. Updating the map does not res ### Choose an instance size at runtime -Set `instance` in `ctx.container.start()` to one of the following named instance types: +Set `instance` in `ctx.container.start()` to one of the following [named instance types](/containers/platform/limits/#instance-types): - `lite` - `standard-1` @@ -166,7 +166,7 @@ One Wrangler configuration can contain applications with both policies. This let ## Related resources -- [Durable Object Container API](/durable-objects/api/container/) +- [Durable Object Container API](/containers/api/durable-object-container/) - [Lifecycle of a Container](/containers/concepts/architecture/) - [Image Management](/containers/guides/image-management/) - [Wrangler Containers configuration](/workers/wrangler/configuration/#containers) diff --git a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx index dff49eebf2b..62d97b351f1 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx @@ -191,4 +191,4 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo - [Scheduling Policies](/containers/configuration/scheduling-policy/) - [Image Management](/containers/guides/image-management/) -- [Durable Object Container API](/durable-objects/api/container/) +- [Durable Object Container API](/containers/api/durable-object-container/) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index e0822bbc775..31aabc22413 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -98,6 +98,42 @@ To update a named image, change its Dockerfile or set `image` to a new digest-pi 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: + + + +```ts +if (!this.ctx.container.running) { + this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + enableInternet: true, + }); +} +``` + + + +To upgrade a running Container immediately, compare its current image with the configured image. Stop and restart the Container when they differ: + + + +```ts +if ((await this.ctx.container.inspect())?.image !== this.ctx.container.images.base) { + if (this.ctx.container.running) { + await this.ctx.container.destroy(); + } + + this.ctx.container.start({ + image: this.ctx.container.images.base, + instance: "standard-2", + enableInternet: true, + }); +} +``` + + + ### Use an external image :::note diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index 3e6746b873c..e082550ef0b 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -8,7 +8,7 @@ description: Save and restore Container filesystems with the Durable Object sche import { TypeScriptExample } from "~/components"; -Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [Durable Object Container API](/durable-objects/api/container/). +Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). The examples on this page use the [Durable Object Container API](/containers/api/durable-object-container/). :::note[Scheduling policy requirement] Snapshots are only supported by Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Applications that use the `default` scheduling policy cannot create or restore snapshots. @@ -76,5 +76,5 @@ You cannot set a custom time-to-live yet. ## Related resources - [Scheduling Policies](/containers/configuration/scheduling-policy/) - Choose how Container instances are configured and updated -- [Durable Object Container](/durable-objects/api/container/) - Full `ctx.container` API reference +- [Durable Object Container API](/containers/api/durable-object-container/) - Full `ctx.container` API reference - [Lifecycle of a Container](/containers/concepts/architecture/) - Understand startup, sleep, and shutdown behavior From 918d4441644bc5860ca43a88c7b8215bdd14bf33 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:47:20 -0400 Subject: [PATCH 31/73] [Containers] Schedule changelog announcements --- .../containers/2026-09-30-durable-object-scheduling-policy.mdx | 3 +-- src/content/changelog/containers/2026-09-30-snapshots.mdx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index b9efebda9b0..cc43b57e188 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -3,8 +3,7 @@ title: New scheduling policy for Containers to configure image and instance from description: The durable_object scheduling policy gives each Durable Object control of Container configuration. products: - containers -date: 2026-09-30 -publish_future_dated_entry: true +date: "2026-09-30T08:45:00-04:00" --- import { TypeScriptExample, WranglerConfig } from "~/components"; diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 134b38a8427..b9160b2b62f 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -3,8 +3,7 @@ title: Snapshot and restore Container state description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers -date: 2026-09-30 -publish_future_dated_entry: true +date: "2026-09-30T08:45:00-04:00" --- import { TypeScriptExample } from "~/components"; From 8b636f00eadcbf6c2a7e6fe78dc5ebd225bb2d44 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:48:52 -0400 Subject: [PATCH 32/73] [Containers] Restore future changelog publication --- .../containers/2026-09-30-durable-object-scheduling-policy.mdx | 3 ++- src/content/changelog/containers/2026-09-30-snapshots.mdx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index cc43b57e188..b9efebda9b0 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -3,7 +3,8 @@ title: New scheduling policy for Containers to configure image and instance from description: The durable_object scheduling policy gives each Durable Object control of Container configuration. products: - containers -date: "2026-09-30T08:45:00-04:00" +date: 2026-09-30 +publish_future_dated_entry: true --- import { TypeScriptExample, WranglerConfig } from "~/components"; diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index b9160b2b62f..134b38a8427 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -3,7 +3,8 @@ title: Snapshot and restore Container state description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers -date: "2026-09-30T08:45:00-04:00" +date: 2026-09-30 +publish_future_dated_entry: true --- import { TypeScriptExample } from "~/components"; From 9a38c8c236631a1d3001c5f0e25f9cb97f117ab2 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:49:05 -0400 Subject: [PATCH 33/73] [Containers] Clarify snapshot changelog title --- src/content/changelog/containers/2026-09-30-snapshots.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 134b38a8427..1af0d041ff5 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -1,5 +1,5 @@ --- -title: Snapshot and restore Container state +title: Snapshot and restore Container filesystem description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers From 04e5be464a9629f3568726eaf49a1ff162bbebbd Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:49:27 -0400 Subject: [PATCH 34/73] [Containers] Schedule changelog announcements --- .../containers/2026-09-30-durable-object-scheduling-policy.mdx | 2 +- src/content/changelog/containers/2026-09-30-snapshots.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index b9efebda9b0..7bf721ed67e 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -3,7 +3,7 @@ title: New scheduling policy for Containers to configure image and instance from description: The durable_object scheduling policy gives each Durable Object control of Container configuration. products: - containers -date: 2026-09-30 +date: "2026-09-30T08:45:00-04:00" publish_future_dated_entry: true --- diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 1af0d041ff5..ac4095f8f3f 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -3,7 +3,7 @@ title: Snapshot and restore Container filesystem description: Persist point-in-time container filesystem with snapshot APIs in public beta. products: - containers -date: 2026-09-30 +date: "2026-09-30T08:45:00-04:00" publish_future_dated_entry: true --- From da8447d3983fe403d2d99d5be48a6603652bcefc Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:50:11 -0400 Subject: [PATCH 35/73] [Containers] Clarify snapshot scheduling policy --- src/content/changelog/containers/2026-09-30-snapshots.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index ac4095f8f3f..43599b4a5f0 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -11,7 +11,7 @@ import { TypeScriptExample } from "~/components"; [Containers](/containers/) now support snapshot APIs in public beta for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. -Use `snapshotContainer()` to capture the full container filesystem. The example uses the [Durable Object Container API](/containers/api/durable-object-container/). Create snapshots from a container that is already running: +Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Use `snapshotContainer()` through the [Durable Object Container API](/containers/api/durable-object-container/) to capture the full container filesystem. Create snapshots from a container that is already running: From 9ac2f444650d6762de961114ea145fdadcf25b9b Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:51:42 -0400 Subject: [PATCH 36/73] [Containers] Clarify snapshot policy requirement --- src/content/docs/containers/api/durable-object-container.mdx | 4 ++-- src/content/docs/containers/concepts/architecture.mdx | 2 +- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 ++ src/content/docs/containers/faq.mdx | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index f566640a502..b617d580fe2 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -102,7 +102,7 @@ this.ctx.container.start({ - `enableInternet` (`boolean`, required): Whether to allow outbound Internet access. Required when you pass `options`. - `image` (`string`, optional): Image reference to start. For an application that uses the `durable_object` scheduling policy, pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). Omit this option when restoring a snapshot. - `instance` (`string | object`, optional): Instance size for an application that uses the `durable_object` scheduling policy. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. - - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional): Full container snapshot to restore before startup. You cannot pass both `containerSnapshot` and `image`. + - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional): Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. #### Return values @@ -217,7 +217,7 @@ For task-oriented examples, refer to [Execute commands](/containers/guides/execu ### `snapshotContainer` -`snapshotContainer()` creates a point-in-time snapshot of the running container filesystem. +`snapshotContainer()` creates a point-in-time snapshot of the running container filesystem. This method is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). diff --git a/src/content/docs/containers/concepts/architecture.mdx b/src/content/docs/containers/concepts/architecture.mdx index 12620e4d1dc..7a936bbea06 100644 --- a/src/content/docs/containers/concepts/architecture.mdx +++ b/src/content/docs/containers/concepts/architecture.mdx @@ -145,7 +145,7 @@ Refer to the [status hooks example](/containers/examples/status-hooks/) for a fu All disk is ephemeral by default. When a Container instance goes to sleep, the next time it starts, it uses a fresh disk from the container image. -If you need point-in-time filesystem state, create and restore a snapshot. +If you need point-in-time filesystem state, Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy) can create and restore a snapshot. Snapshots are immutable, so later file changes require a new snapshot. For more information, refer to [Snapshots](/containers/guides/snapshots/). diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 2ee210615be..7bfde9c8970 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -154,6 +154,8 @@ The runtime uses camel case (`memoryMib` and `diskMb`). Wrangler's application-l ### Start from an image or snapshot +Snapshot creation and restore are only supported for applications that use the `durable_object` scheduling policy. Applications that use the `default` policy cannot create or restore snapshots. + For a new filesystem, pass `image` to `ctx.container.start()`. To restore a full filesystem snapshot, pass `containerSnapshot` instead. `image` and `containerSnapshot` are mutually exclusive because a snapshot already identifies the filesystem to restore. Refer to [Snapshots](/containers/guides/snapshots/) for the complete save and restore flow. diff --git a/src/content/docs/containers/faq.mdx b/src/content/docs/containers/faq.mdx index 9c0aaa765a0..edc78700af3 100644 --- a/src/content/docs/containers/faq.mdx +++ b/src/content/docs/containers/faq.mdx @@ -107,7 +107,7 @@ Refer to [image management](/containers/guides/image-management/#use-pre-built-c All disk is ephemeral by default. When a Container instance goes to sleep, the next time it starts, it uses a fresh disk from the container image. -If you need point-in-time filesystem state, create and restore a snapshot. +If you need point-in-time filesystem state, Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy) can create and restore a snapshot. Snapshots are immutable, so later file changes require a new snapshot. For more information, refer to [Snapshots](/containers/guides/snapshots/). From 21d5f29be67e5b1a449b150120448c77f872d6c3 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:52:04 -0400 Subject: [PATCH 37/73] [Containers] Highlight managed Debian image --- ...-09-30-durable-object-scheduling-policy.mdx | 4 +++- .../configuration/scheduling-policy/index.mdx | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index 7bf721ed67e..00febabd811 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -11,7 +11,7 @@ import { TypeScriptExample, WranglerConfig } from "~/components"; [Containers](/containers/) now support the `durable_object` scheduling policy in public beta. This policy lets a Durable Object select the image and instance size for a Container at runtime instead of using one centrally managed configuration for the application. -Configure the policy and one or more named images in Wrangler: +To use custom images, configure the policy and one or more named images in Wrangler: @@ -47,6 +47,8 @@ this.ctx.container.start({ +The `durable_object` policy also supports the [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image), which includes Node.js 24.20.0 on Debian Trixie slim. Start it directly without configuring a named image. + Durable Object-managed Container instances have independent lifecycles and do not participate in application-wide image rollouts. For configuration, runtime sizing, snapshots, and update behavior, refer to [Scheduling Policies](/containers/configuration/scheduling-policy/). diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 7bfde9c8970..32a5f02e66b 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -51,7 +51,7 @@ When you change the image or instance type and deploy, Cloudflare rolls out that The `durable_object` policy moves per-instance decisions into your Durable Object. Wrangler associates the Container application with the Durable Object class, and your code supplies a startup image or snapshot and an optional instance size to `ctx.container.start()`. -Configure the policy and the images that the Durable Object can start: +Configure the policy. To use custom images, add the images that the Durable Object can start: @@ -116,6 +116,22 @@ export class AgentComputer extends DurableObject { `ctx.container.start()` initiates startup and returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic or calling [`exec()`](/containers/api/durable-object-container/#exec). +### Use the Cloudflare-managed image + +If you do not need a custom image, start the [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) directly without adding a named image to Wrangler. It includes Node.js 24.20.0 on Debian Trixie slim: + + + +```ts +this.ctx.container.start({ + image: "cloudflare/debian-trixie", + instance: "standard-2", + enableInternet: true, +}); +``` + + + ### Configure named images Each key in `images` is a name you choose. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. Wrangler builds and uploads the image. You can also set `build_context` and `build_vars` for that image. From 11e469d50d98695078ffd713ed4b6d04e47daf92 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:53:18 -0400 Subject: [PATCH 38/73] [Containers] Reposition snapshot policy note --- src/content/changelog/containers/2026-09-30-snapshots.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 43599b4a5f0..7cf3734f313 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -11,7 +11,7 @@ import { TypeScriptExample } from "~/components"; [Containers](/containers/) now support snapshot APIs in public beta for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. -Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Use `snapshotContainer()` through the [Durable Object Container API](/containers/api/durable-object-container/) to capture the full container filesystem. Create snapshots from a container that is already running: +Use `snapshotContainer()` through the [Durable Object Container API](/containers/api/durable-object-container/) to capture the full container filesystem. Create snapshots from a container that is already running: @@ -52,6 +52,10 @@ export class MyDurableObject extends DurableObject { +:::note[Scheduling policy requirement] +Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). +::: + Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. For more information, refer to [Snapshots](/containers/guides/snapshots/) and the [Durable Object Container API](/containers/api/durable-object-container/). From 0dcf4b6143a34ccdccf47e90fa25f0c9d02f7cfd Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:54:53 -0400 Subject: [PATCH 39/73] [Containers] Use prose for snapshot policy --- src/content/changelog/containers/2026-09-30-snapshots.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index 7cf3734f313..d457de8c44b 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -52,9 +52,7 @@ export class MyDurableObject extends DurableObject { -:::note[Scheduling policy requirement] Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). -::: Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. From 4f9e5af7950b8a73dc9c118e8c33ffc730f51cc0 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 18:55:40 -0400 Subject: [PATCH 40/73] [Containers] Combine snapshot changelog example --- .../containers/2026-09-30-snapshots.mdx | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/content/changelog/containers/2026-09-30-snapshots.mdx b/src/content/changelog/containers/2026-09-30-snapshots.mdx index d457de8c44b..bb62965c3fb 100644 --- a/src/content/changelog/containers/2026-09-30-snapshots.mdx +++ b/src/content/changelog/containers/2026-09-30-snapshots.mdx @@ -11,7 +11,7 @@ import { TypeScriptExample } from "~/components"; [Containers](/containers/) now support snapshot APIs in public beta for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object. -Use `snapshotContainer()` through the [Durable Object Container API](/containers/api/durable-object-container/) to capture the full container filesystem. Create snapshots from a container that is already running: +Use `snapshotContainer()` through the [Durable Object Container API](/containers/api/durable-object-container/) to capture the full container filesystem. Create a snapshot from a running Container, store its handle, and pass that handle to `start()` when you restore it later: @@ -20,24 +20,14 @@ import { DurableObject } from "cloudflare:workers"; export class MyDurableObject extends DurableObject { async saveSnapshot() { + // Create a snapshot from the running Container. const containerSnapshot = await this.ctx.container.snapshotContainer({}); await this.ctx.storage.put("containerSnapshot", containerSnapshot); } -} -``` - - - -Later, load the saved snapshot handle and restore it with `start()`: - - - -```ts -import { DurableObject } from "cloudflare:workers"; -export class MyDurableObject extends DurableObject { async restoreSnapshot() { + // Restore the saved snapshot later. const containerSnapshot = await this.ctx.storage.get("containerSnapshot"); @@ -52,8 +42,6 @@ export class MyDurableObject extends DurableObject { -Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). - -Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. +Snapshots are only supported for Container applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Snapshots are immutable, so create a new snapshot to persist filesystem changes made after a restore. For more information, refer to [Snapshots](/containers/guides/snapshots/) and the [Durable Object Container API](/containers/api/durable-object-container/). From 60f410efb1b7c49eccdf0ccc9ad2f0e857711513 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:05:55 -0400 Subject: [PATCH 41/73] [Containers] Clarify new managed image --- .../containers/2026-09-30-durable-object-scheduling-policy.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx index 00febabd811..ac287278b9d 100644 --- a/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx +++ b/src/content/changelog/containers/2026-09-30-durable-object-scheduling-policy.mdx @@ -47,7 +47,7 @@ this.ctx.container.start({ -The `durable_object` policy also supports the [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image), which includes Node.js 24.20.0 on Debian Trixie slim. Start it directly without configuring a named image. +The `durable_object` policy also supports the new [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image), which includes Node.js 24.20.0 on Debian Trixie slim. Start it directly without configuring a named image. Durable Object-managed Container instances have independent lifecycles and do not participate in application-wide image rollouts. From be747110a8891a7b98418b5858d3b3589c062212 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:10:12 -0400 Subject: [PATCH 42/73] [Containers] Simplify images attribute example --- .../docs/containers/api/durable-object-container.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index b617d580fe2..01de4723c57 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -58,14 +58,10 @@ export class MyDurableObject extends DurableObject { `images` is a read-only map of named images configured for an application that uses the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Each value is a digest-pinned image reference prepared by Wrangler. - - -```ts +```js const image = this.ctx.container.images.base; ``` - - Pass a value from this map as the `image` option to [`start()`](#start). ### `running` From 391a4debfb655d315d005a16bc5f43ef8e9868f8 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:13:03 -0400 Subject: [PATCH 43/73] [Containers] Label policy-specific images attribute --- src/content/docs/containers/api/durable-object-container.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 01de4723c57..4890ce9aaca 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -9,7 +9,7 @@ products: - durable-objects --- -import { TypeScriptExample } from "~/components"; +import { Badge, TypeScriptExample } from "~/components"; Each [container](/containers/) is managed and proxied by a Durable Object. The Durable Object manages routing and persistent state. The container process runs your image inside a Linux VM. @@ -54,7 +54,7 @@ export class MyDurableObject extends DurableObject { ## Attributes -### `images` +### `images` `images` is a read-only map of named images configured for an application that uses the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Each value is a digest-pinned image reference prepared by Wrangler. From b47443c1957521fe8fa1d887e1a71e8a07c38744 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:15:14 -0400 Subject: [PATCH 44/73] [Containers] Clarify scheduling policy API support --- src/content/docs/containers/api/container-class.mdx | 4 ++++ src/content/docs/containers/api/durable-object-container.mdx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/content/docs/containers/api/container-class.mdx b/src/content/docs/containers/api/container-class.mdx index 2d1cdfacf7c..cf98f4b8451 100644 --- a/src/content/docs/containers/api/container-class.mdx +++ b/src/content/docs/containers/api/container-class.mdx @@ -12,6 +12,10 @@ import { PackageManagers, TypeScriptExample } from "~/components"; The [`Container` class](https://github.com/cloudflare/containers) from [`@cloudflare/containers`](https://www.npmjs.com/package/@cloudflare/containers) provides lifecycle helpers for container instances. For direct lifecycle control, use the [Durable Object Container API](/containers/api/durable-object-container/). +:::note +The `Container` class does not support applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). It is available only with the `default` scheduling policy. For `durable_object` applications, use the [Durable Object Container API](/containers/api/durable-object-container/). +::: + To move an existing application to direct control, refer to [Migrate to the Durable Object Container API](/containers/guides/migrate-to-durable-object-container-api/). **`Container` extends [`DurableObject`](/durable-objects/api/base/).** The Durable Object manages routing, persistent state, and lifecycle hooks, while the container process runs your image inside a Linux VM. Because your subclass is a Durable Object, you have access to the full Durable Object API — including [`this.ctx.storage`](/durable-objects/api/sqlite-storage-api/) for persistent SQLite-backed storage and [`this.ctx.id`](/durable-objects/api/id/) for the unique instance identifier. Use Durable Object storage to persist state that should survive container restarts, such as configuration, user data, or task results. diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 4890ce9aaca..4e86b43f648 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -211,7 +211,7 @@ With `stderr: "combined"`, `stderr` is `null` on `ExecProcess` and an empty `Arr For task-oriented examples, refer to [Execute commands](/containers/guides/execute-commands/). -### `snapshotContainer` +### `snapshotContainer` `snapshotContainer()` creates a point-in-time snapshot of the running container filesystem. This method is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). From 8c5e8734549adf572368ca457ffb65709456435f Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:17:39 -0400 Subject: [PATCH 45/73] [Containers] Label snapshot restore parameter --- src/content/docs/containers/api/durable-object-container.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 4e86b43f648..a3fa924bb28 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -98,7 +98,7 @@ this.ctx.container.start({ - `enableInternet` (`boolean`, required): Whether to allow outbound Internet access. Required when you pass `options`. - `image` (`string`, optional): Image reference to start. For an application that uses the `durable_object` scheduling policy, pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). Omit this option when restoring a snapshot. - `instance` (`string | object`, optional): Instance size for an application that uses the `durable_object` scheduling policy. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. - - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional): Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. + - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional) : Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. #### Return values From 35071dcf2f24cc79c199683237620776e68e3cb8 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:18:30 -0400 Subject: [PATCH 46/73] [Containers] Reorder Container class guidance --- src/content/docs/containers/api/container-class.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/api/container-class.mdx b/src/content/docs/containers/api/container-class.mdx index cf98f4b8451..7265626120e 100644 --- a/src/content/docs/containers/api/container-class.mdx +++ b/src/content/docs/containers/api/container-class.mdx @@ -12,14 +12,14 @@ import { PackageManagers, TypeScriptExample } from "~/components"; The [`Container` class](https://github.com/cloudflare/containers) from [`@cloudflare/containers`](https://www.npmjs.com/package/@cloudflare/containers) provides lifecycle helpers for container instances. For direct lifecycle control, use the [Durable Object Container API](/containers/api/durable-object-container/). +**`Container` extends [`DurableObject`](/durable-objects/api/base/).** The Durable Object manages routing, persistent state, and lifecycle hooks, while the container process runs your image inside a Linux VM. Because your subclass is a Durable Object, you have access to the full Durable Object API — including [`this.ctx.storage`](/durable-objects/api/sqlite-storage-api/) for persistent SQLite-backed storage and [`this.ctx.id`](/durable-objects/api/id/) for the unique instance identifier. Use Durable Object storage to persist state that should survive container restarts, such as configuration, user data, or task results. + :::note The `Container` class does not support applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). It is available only with the `default` scheduling policy. For `durable_object` applications, use the [Durable Object Container API](/containers/api/durable-object-container/). ::: To move an existing application to direct control, refer to [Migrate to the Durable Object Container API](/containers/guides/migrate-to-durable-object-container-api/). -**`Container` extends [`DurableObject`](/durable-objects/api/base/).** The Durable Object manages routing, persistent state, and lifecycle hooks, while the container process runs your image inside a Linux VM. Because your subclass is a Durable Object, you have access to the full Durable Object API — including [`this.ctx.storage`](/durable-objects/api/sqlite-storage-api/) for persistent SQLite-backed storage and [`this.ctx.id`](/durable-objects/api/id/) for the unique instance identifier. Use Durable Object storage to persist state that should survive container restarts, such as configuration, user data, or task results. - Then, define a class that extends `Container` and set the shared properties on the class: From 3db7b791b5877fbdc0ccff9334d789a24d5fd0d5 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:19:49 -0400 Subject: [PATCH 47/73] [Containers] Separate Container class setup --- src/content/docs/containers/api/container-class.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/docs/containers/api/container-class.mdx b/src/content/docs/containers/api/container-class.mdx index 7265626120e..3c128d03f52 100644 --- a/src/content/docs/containers/api/container-class.mdx +++ b/src/content/docs/containers/api/container-class.mdx @@ -20,6 +20,8 @@ The `Container` class does not support applications that use the [`durable_objec To move an existing application to direct control, refer to [Migrate to the Durable Object Container API](/containers/guides/migrate-to-durable-object-container-api/). +## Use the Container class + Then, define a class that extends `Container` and set the shared properties on the class: From 0490c981bf858fbbcee3ec4f4718f523e2bb4154 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:20:46 -0400 Subject: [PATCH 48/73] [Containers] Introduce Container class setup --- src/content/docs/containers/api/container-class.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/docs/containers/api/container-class.mdx b/src/content/docs/containers/api/container-class.mdx index 3c128d03f52..9a1b81fdf9c 100644 --- a/src/content/docs/containers/api/container-class.mdx +++ b/src/content/docs/containers/api/container-class.mdx @@ -22,6 +22,8 @@ To move an existing application to direct control, refer to [Migrate to the Dura ## Use the Container class +Start by installing the `@cloudflare/containers` package: + Then, define a class that extends `Container` and set the shared properties on the class: From 926cce6de047a7e141239c6fca511d20722aa3ba Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:23:02 -0400 Subject: [PATCH 49/73] [Containers] Link images attribute to Wrangler configuration --- src/content/docs/containers/api/durable-object-container.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index a3fa924bb28..296d8a8729c 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -56,7 +56,7 @@ export class MyDurableObject extends DurableObject { ### `images` -`images` is a read-only map of named images configured for an application that uses the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). Each value is a digest-pinned image reference prepared by Wrangler. +`images` is a read-only map generated from the [`images` field in the application's Wrangler configuration](/workers/wrangler/configuration/#durable_object-scheduling-policy). Wrangler builds or resolves each named image and exposes its digest-pinned reference under the same key. This attribute is available only for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). ```js const image = this.ctx.container.images.base; From ca9b2664d204f07f665f598bde075d9fda61fc6f Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:25:30 -0400 Subject: [PATCH 50/73] [Containers] Distinguish start options by policy --- .../api/durable-object-container.mdx | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 296d8a8729c..8e13865ad6d 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -78,26 +78,31 @@ this.ctx.container.running; `start()` boots a container. It returns before the container is ready to accept requests. Confirm readiness before sending traffic. - +The required options depend on the application's scheduling policy. -```ts +**`default` scheduling policy:** The image and instance size come from Wrangler configuration, so `start()` does not require any options: + +```js +this.ctx.container.start(); +``` + +**`durable_object` scheduling policy:** Pass an image and explicitly choose whether to allow outbound Internet access. You can optionally select an instance size: + +```js this.ctx.container.start({ image: this.ctx.container.images.base, - instance: "standard-2", enableInternet: true, }); ``` - - #### Parameters -- `options` (`object`, optional): Common container startup options: +- `options` (`object`, conditionally required): Startup options. Required for applications that use the `durable_object` scheduling policy and optional for applications that use the `default` scheduling policy. - `env` (`Record`, optional): Environment variables to pass to the container. - `entrypoint` (`string[]`, optional): Command and arguments to run in the container. - `enableInternet` (`boolean`, required): Whether to allow outbound Internet access. Required when you pass `options`. - - `image` (`string`, optional): Image reference to start. For an application that uses the `durable_object` scheduling policy, pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). Omit this option when restoring a snapshot. - - `instance` (`string | object`, optional): Instance size for an application that uses the `durable_object` scheduling policy. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. + - `image` (`string`, conditionally required) : Image reference to start. Required unless you pass `containerSnapshot`. Pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). + - `instance` (`string | object`, optional) : Instance size. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional) : Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. #### Return values From 6d85d0cec248f705b77587c2e4467672dcb8a301 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:26:48 -0400 Subject: [PATCH 51/73] [Containers] Document ContainerInfo and start labels --- src/content/docs/containers/api/durable-object-container.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 8e13865ad6d..069341a2f8e 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -104,6 +104,7 @@ this.ctx.container.start({ - `image` (`string`, conditionally required) : Image reference to start. Required unless you pass `containerSnapshot`. Pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). - `instance` (`string | object`, optional) : Instance size. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional) : Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. + - `labels` (`Record`, optional): Up to 10 labels that [`inspect()`](#inspect) returns. Label names must contain 1 to 16 bytes. Label values can contain up to 64 bytes. Names and values cannot contain control characters. #### Return values @@ -127,7 +128,9 @@ const containerInfo = await this.ctx.container.inspect(); #### Return values -- `Promise`: Resolves with the running container information or `null`. +- `Promise`: Resolves with `null` when no container is running. Otherwise, it resolves with a `ContainerInfo` object containing: + - `image` (`string`): Image reference reported by the runtime. The value can be an empty string. + - `labels` (`Record`): Labels passed to [`start()`](#start). ### `exec` From 0557d4e04dd7acc8b02ddd3c4d4e05c807761282 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:28:07 -0400 Subject: [PATCH 52/73] [Containers] Combine start policy examples --- .../docs/containers/api/durable-object-container.mdx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 069341a2f8e..ea021f7e115 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -80,15 +80,14 @@ this.ctx.container.running; The required options depend on the application's scheduling policy. -**`default` scheduling policy:** The image and instance size come from Wrangler configuration, so `start()` does not require any options: - ```js +// `default` scheduling policy: +// The image and instance size come from Wrangler configuration. this.ctx.container.start(); -``` -**`durable_object` scheduling policy:** Pass an image and explicitly choose whether to allow outbound Internet access. You can optionally select an instance size: - -```js +// `durable_object` scheduling policy: +// Pass an image and choose whether to allow outbound Internet access. +// The instance size is optional. this.ctx.container.start({ image: this.ctx.container.images.base, enableInternet: true, From 9d80681a8caeed29535d39a20bd72d34291e9c48 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:28:18 -0400 Subject: [PATCH 53/73] [Containers] Define ContainerSnapshot return value --- .../docs/containers/api/durable-object-container.mdx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index ea021f7e115..0ccb81aa14a 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -102,7 +102,7 @@ this.ctx.container.start({ - `enableInternet` (`boolean`, required): Whether to allow outbound Internet access. Required when you pass `options`. - `image` (`string`, conditionally required) : Image reference to start. Required unless you pass `containerSnapshot`. Pass the [`cloudflare/debian-trixie` managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) or a value from [`ctx.container.images`](#images). - `instance` (`string | object`, optional) : Instance size. Pass `"lite"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, `"standard-4"`, or a custom object with `vcpu`, `memoryMib`, and `diskMb` properties. Defaults to `"lite"`. - - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional) : Full container snapshot to restore before startup. Snapshot restore is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). You cannot pass both `containerSnapshot` and `image`. + - `containerSnapshot` (`ContainerSnapshotRestoreParams`, optional) : Snapshot handle to restore before startup. Pass the `ContainerSnapshot` returned by [`snapshotContainer()`](#snapshotcontainer), or an object containing its `id`. You cannot pass both `containerSnapshot` and `image`. - `labels` (`Record`, optional): Up to 10 labels that [`inspect()`](#inspect) returns. Label names must contain 1 to 16 bytes. Label values can contain up to 64 bytes. Names and values cannot contain control characters. #### Return values @@ -239,7 +239,10 @@ const snapshot = await this.ctx.container.snapshotContainer({ #### Return values -- `Promise`: Resolves with a snapshot containing `id`, `size`, and an optional `name`. +- `Promise`: Resolves with an opaque handle for the stored filesystem snapshot. The snapshot data is not returned to the Worker. The handle contains: + - `id` (`string`): Unique snapshot identifier. Pass the returned `ContainerSnapshot` to [`start()`](#start) as `containerSnapshot`, or store it for a later restore. + - `size` (`number`): Snapshot size in bytes. + - `name` (`string`, optional): Human-readable name supplied in `options`. Container snapshots are immutable. Snapshot handles currently have an implicit 30-day time-to-live that refreshes when you restore them. For the complete save and restore flow, refer to [Use snapshots](/containers/guides/snapshots/). From d57f6d8aff4cfe99897723e800df6121147c3cfe Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:28:34 -0400 Subject: [PATCH 54/73] [Containers] Simplify inspect example --- .../docs/containers/api/durable-object-container.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 0ccb81aa14a..fa11dcc710b 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -113,14 +113,10 @@ this.ctx.container.start({ `inspect()` returns the image and labels for a running container. It returns `null` when no container is running. - - -```ts +```js const containerInfo = await this.ctx.container.inspect(); ``` - - #### Parameters - None. From 9a8b6493f7b100ffd1b38a2c7ba7c58ce86761c0 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:28:41 -0400 Subject: [PATCH 55/73] [Containers] Simplify snapshot API example --- .../docs/containers/api/durable-object-container.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index fa11dcc710b..df8b70d84eb 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -218,16 +218,12 @@ For task-oriented examples, refer to [Execute commands](/containers/guides/execu `snapshotContainer()` creates a point-in-time snapshot of the running container filesystem. This method is only supported for applications that use the [`durable_object` scheduling policy](/containers/configuration/scheduling-policy/#use-the-durable-object-scheduling-policy). - - -```ts +```js const snapshot = await this.ctx.container.snapshotContainer({ name: "before-upgrade", }); ``` - - #### Parameters - `options` (`ContainerSnapshotOptions`): Snapshot configuration: From fa263ca46e0917d32911182bdbbde0b137de38f3 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:29:22 -0400 Subject: [PATCH 56/73] [Containers] Note default start instance size --- src/content/docs/containers/api/durable-object-container.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index df8b70d84eb..e46fcd787a4 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -87,7 +87,7 @@ this.ctx.container.start(); // `durable_object` scheduling policy: // Pass an image and choose whether to allow outbound Internet access. -// The instance size is optional. +// The instance size is optional and defaults to "lite". this.ctx.container.start({ image: this.ctx.container.images.base, enableInternet: true, From 98c7d0446741e679483569ca1b1b64cdb853b9da Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:34:16 -0400 Subject: [PATCH 57/73] [Containers] Clarify application-controlled image updates --- src/content/docs/containers/concepts/architecture.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/concepts/architecture.mdx b/src/content/docs/containers/concepts/architecture.mdx index 7a936bbea06..3ac7bdf3d11 100644 --- a/src/content/docs/containers/concepts/architecture.mdx +++ b/src/content/docs/containers/concepts/architecture.mdx @@ -12,7 +12,7 @@ products: How images and running Container instances update depends on the [scheduling policy](/containers/configuration/scheduling-policy/) for the application. -With the `durable_object` policy, Wrangler prepares the named images for the application. Durable Object code can access their immutable references and selects an image and instance size when it calls `ctx.container.start()`. When an image reference changes, the Durable Object decides whether to stop the running Container and start it with the new image or let it continue with the previous image. This application-controlled restart is how you roll out image changes with the `durable_object` policy. These instances do not participate in application-wide image rollouts. +With the `durable_object` policy, Wrangler prepares the named images for the application. Durable Object code can access their immutable references and selects an image and instance size when it calls `ctx.container.start()`. When an image reference changes, the Durable Object code decides whether to stop the running Container and start it with the new image or let it continue with the previous image. This application-controlled restart is how you roll out image changes with the `durable_object` policy. These instances do not participate in application-wide image rollouts. With the `default` policy, Wrangler uploads or resolves the application image. Cloudflare distributes that image across its network and prepares capacity for new instances. Changes to the image or instance type use a [rollout](/containers/configuration/rollouts/). From 0cce88600cf1726183dbfcdd70a71cef0409f6dc Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:39:07 -0400 Subject: [PATCH 58/73] [Containers] Move scheduling policy migration to guides --- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- .../guides/migrate-to-durable-object-container-api.mdx | 2 +- .../migrate-to-durable-object-scheduling-policy.mdx} | 4 ++-- src/content/docs/containers/guides/snapshots.mdx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/content/docs/containers/{configuration/scheduling-policy/move-from-default.mdx => guides/migrate-to-durable-object-scheduling-policy.mdx} (99%) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 32a5f02e66b..4447855481f 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -17,7 +17,7 @@ A scheduling policy determines where you configure a Container image and instanc | `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | | `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | -The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Move to the Durable Object scheduling policy](/containers/configuration/scheduling-policy/move-from-default/). +The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Migrate to the Durable Object scheduling policy](/containers/guides/migrate-to-durable-object-scheduling-policy/). :::note The `durable_object` scheduling policy is in public beta. diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx index ba0ae66d661..7c137c1c020 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx @@ -3,7 +3,7 @@ title: Migrate from the Container class to the Durable Object Container API description: Replace Container class lifecycle and routing helpers with direct container control inside a Durable Object. pcx_content_type: how-to sidebar: - order: 7 + order: 6 products: - containers - durable-objects diff --git a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx similarity index 99% rename from src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx rename to src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx index 62d97b351f1..1ff4304e6c2 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/move-from-default.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx @@ -1,9 +1,9 @@ --- pcx_content_type: how-to -title: Move to the Durable Object scheduling policy +title: Migrate to the Durable Object scheduling policy description: Replace a Container application that uses the default scheduling policy with a Durable Object-managed application. sidebar: - order: 1 + order: 7 products: - containers --- diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index e082550ef0b..d3b11d5c71a 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -2,7 +2,7 @@ title: Use snapshots pcx_content_type: how-to sidebar: - order: 7 + order: 8 description: Save and restore Container filesystems with the Durable Object scheduling policy. --- From b169147cbe02868bec07faffa74c3cd63f1e6a8b Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:40:12 -0400 Subject: [PATCH 59/73] [Containers] Link scheduling policy rollouts --- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 4447855481f..7cb9eda0903 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -10,7 +10,7 @@ products: import { TypeScriptExample, WranglerConfig } from "~/components"; -A scheduling policy determines where you configure a Container image and instance size. It also determines how image updates apply. Choose the policy when you create the Container application. +A scheduling policy determines where you configure a Container image and instance size. It also determines how image updates and [rollouts](/containers/configuration/rollouts/) apply. Choose the policy when you create the Container application. | Policy | Configure image and instance size | Image updates | Best for | | ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | From e25ebfd0772c12f154161e6eac5618e6261e5667 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:41:38 -0400 Subject: [PATCH 60/73] [Containers] Reorder migration guides after snapshots --- .../guides/migrate-to-durable-object-container-api.mdx | 2 +- .../guides/migrate-to-durable-object-scheduling-policy.mdx | 2 +- src/content/docs/containers/guides/snapshots.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx index 7c137c1c020..ba0ae66d661 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-container-api.mdx @@ -3,7 +3,7 @@ title: Migrate from the Container class to the Durable Object Container API description: Replace Container class lifecycle and routing helpers with direct container control inside a Durable Object. pcx_content_type: how-to sidebar: - order: 6 + order: 7 products: - containers - durable-objects diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx index 1ff4304e6c2..19548369179 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx @@ -3,7 +3,7 @@ pcx_content_type: how-to title: Migrate to the Durable Object scheduling policy description: Replace a Container application that uses the default scheduling policy with a Durable Object-managed application. sidebar: - order: 7 + order: 8 products: - containers --- diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index d3b11d5c71a..5664ef3d9b2 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -2,7 +2,7 @@ title: Use snapshots pcx_content_type: how-to sidebar: - order: 8 + order: 6 description: Save and restore Container filesystems with the Durable Object scheduling policy. --- From a40f87dfe11773d580f728bcc9f3f944cc20eaf4 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:43:31 -0400 Subject: [PATCH 61/73] [Containers] Make scheduling policy docs timeless --- src/content/docs/containers/api/durable-object-container.mdx | 2 +- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- src/content/docs/containers/guides/image-management.mdx | 2 +- src/content/docs/containers/guides/snapshots.mdx | 2 +- src/content/docs/workers/wrangler/configuration.mdx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index e46fcd787a4..c946749c042 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -236,7 +236,7 @@ const snapshot = await this.ctx.container.snapshotContainer({ - `size` (`number`): Snapshot size in bytes. - `name` (`string`, optional): Human-readable name supplied in `options`. -Container snapshots are immutable. Snapshot handles currently have an implicit 30-day time-to-live that refreshes when you restore them. For the complete save and restore flow, refer to [Use snapshots](/containers/guides/snapshots/). +Container snapshots are immutable. Snapshot handles have an implicit 30-day time-to-live that refreshes when you restore them. For the complete save and restore flow, refer to [Use snapshots](/containers/guides/snapshots/). ### `destroy` diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 7cb9eda0903..1c052b87340 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -25,7 +25,7 @@ The `durable_object` scheduling policy is in public beta. ## Use the default scheduling policy -The `default` policy preserves the existing Containers behavior. Define one `image`, one `instance_type`, and application-level settings such as `max_instances` in Wrangler configuration. Omitting `scheduling_policy` selects `default`. +With the `default` policy, Wrangler configuration defines one application-wide `image`, one `instance_type`, and settings such as `max_instances`. Omitting `scheduling_policy` selects `default`. diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 31aabc22413..c5464889859 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -137,7 +137,7 @@ if ((await this.ctx.container.inspect())?.image !== this.ctx.container.images.ba ### Use an external image :::note -The `durable_object` scheduling policy does not support direct image references from external registries at this time. A named `image` source must use a digest-pinned reference from the Cloudflare managed registry. +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](#use-images-from-other-registries). Then, configure the resulting digest-pinned reference as a named image. diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index 5664ef3d9b2..edadfd0651a 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -69,7 +69,7 @@ export class MyDurableObject extends DurableObject { ## Understand retention -Snapshots currently have an implicit 30-day time-to-live. Each restore refreshes that time-to-live. +Snapshots have an implicit 30-day time-to-live. Each restore refreshes that time-to-live. You cannot set a custom time-to-live yet. diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 33a05b897e1..06a417600d1 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1335,7 +1335,7 @@ The following options are available: name, and your environment. - Required when `class_name` is omitted so that `exports..container` can reference the Container. - `instance_type` - - The instance type determines the amount of memory, CPU, and disk given to the container instance. The current options are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, see the [instance types documentation](/containers/platform/limits/#instance-types). + - The instance type determines the amount of memory, CPU, and disk given to the container instance. Supported values are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, refer to [Limits and Instance Types](/containers/platform/limits/#instance-types). - To specify a custom instance type, see [Custom instance types](#custom-instance-types). - `max_instances` - The maximum number of concurrent container instances. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. From 34e6fd5fde2cb2431e199fdc8328e335a7cd4c25 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:45:57 -0400 Subject: [PATCH 62/73] [Containers] Prefer declarative Durable Object exports --- .../containers/configuration/rollouts.mdx | 10 ++++----- .../configuration/scheduling-policy/index.mdx | 20 +++++++---------- ...te-to-durable-object-scheduling-policy.mdx | 22 +++++++++---------- src/content/docs/containers/index.mdx | 10 ++++----- .../docs/workers/wrangler/configuration.mdx | 20 ++++++++--------- 5 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/content/docs/containers/configuration/rollouts.mdx b/src/content/docs/containers/configuration/rollouts.mdx index c283d3522c0..b6552166590 100644 --- a/src/content/docs/containers/configuration/rollouts.mdx +++ b/src/content/docs/containers/configuration/rollouts.mdx @@ -148,12 +148,12 @@ Use none when the deploy should not publish a new image or start a container ins }, ], }, - "migrations": [ - { - "tag": "v1", - "new_sqlite_classes": ["MyContainer"], + "exports": { + "MyContainer": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 1c052b87340..84c1fd21860 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -59,7 +59,7 @@ Configure the policy. To use custom images, add the images that the Durable Obje { "name": "agent-computer", "main": "src/index.ts", - "compatibility_date": "$today", + "compatibility_date": "2026-09-29", "containers": [ { "class_name": "AgentComputer", @@ -79,12 +79,12 @@ Configure the policy. To use custom images, add the images that the Durable Obje }, ], }, - "migrations": [ - { - "tag": "v1", - "new_sqlite_classes": ["AgentComputer"], + "exports": { + "AgentComputer": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` @@ -120,9 +120,7 @@ export class AgentComputer extends DurableObject { If you do not need a custom image, start the [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) directly without adding a named image to Wrangler. It includes Node.js 24.20.0 on Debian Trixie slim: - - -```ts +```js this.ctx.container.start({ image: "cloudflare/debian-trixie", instance: "standard-2", @@ -130,11 +128,9 @@ this.ctx.container.start({ }); ``` - - ### Configure named images -Each key in `images` is a name you choose. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. Wrangler builds and uploads the image. You can also set `build_context` and `build_vars` for that image. +Each key under a `durable_object` application's `containers[].images` configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. Wrangler builds and uploads the image. You can also set `build_context` and `build_vars` for that image. Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx index 19548369179..d5d1f5a69b7 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx @@ -52,11 +52,11 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo Add a new SQLite-backed Durable Object class and binding. Keep the existing class and binding so that you can route traffic back to them. - Use the Durable Object lifecycle configuration already used by your Worker. If the Worker uses the legacy `migrations` array, append a migration with the replacement class in `new_sqlite_classes`. If it uses `exports`, declare the replacement class there. Do not switch between `migrations` and `exports` as part of this process. + Use the declarative `exports` field to define both SQLite-backed Durable Object classes. Keep the existing class exported while you add the replacement class. 2. **Add a replacement Container application.** - Keep the existing application and add a differently named application with the `durable_object` policy. The following example uses the legacy `migrations` array: + Keep the existing application and add a differently named application with the `durable_object` policy: @@ -64,7 +64,7 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo { "name": "sandbox-worker", "main": "src/index.ts", - "compatibility_date": "$today", + "compatibility_date": "2026-09-29", "containers": [ { "name": "sandbox-default", @@ -97,16 +97,16 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo }, ], }, - "migrations": [ - { - "tag": "v1", - "new_sqlite_classes": ["LegacySandbox"], + "exports": { + "LegacySandbox": { + "type": "durable-object", + "storage": "sqlite", }, - { - "tag": "v2", - "new_sqlite_classes": ["DurableSandbox"], + "DurableSandbox": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` diff --git a/src/content/docs/containers/index.mdx b/src/content/docs/containers/index.mdx index 7401ac4980e..5bb537ffbfe 100644 --- a/src/content/docs/containers/index.mdx +++ b/src/content/docs/containers/index.mdx @@ -162,12 +162,12 @@ export async function startAndWaitForPort( }, ], }, - "migrations": [ - { - "new_sqlite_classes": ["MyContainer"], - "tag": "v1", + "exports": { + "MyContainer": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 06a417600d1..8a03c5f2e07 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1394,12 +1394,12 @@ The following options are available: }, ], }, - "migrations": [ - { - "tag": "v1", - "new_sqlite_classes": ["MyContainer"], + "exports": { + "MyContainer": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` @@ -1457,12 +1457,12 @@ Name one or more images and select one from Durable Object code when the Contain }, ], }, - "migrations": [ - { - "tag": "v1", - "new_sqlite_classes": ["AgentComputer"], + "exports": { + "AgentComputer": { + "type": "durable-object", + "storage": "sqlite", }, - ], + }, } ``` From b71070b942ebcae151c765c3b99e0002cdd0b569 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:47:04 -0400 Subject: [PATCH 63/73] [Containers] Clarify when named images are built --- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index 84c1fd21860..aeb9f4e2ece 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -130,7 +130,7 @@ this.ctx.container.start({ ### Configure named images -Each key under a `durable_object` application's `containers[].images` configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. Wrangler builds and uploads the image. You can also set `build_context` and `build_vars` for that image. +Each key under a `durable_object` application's `containers[].images` configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. When you run `wrangler deploy`, Wrangler builds and uploads that image. You can also set `build_context` and `build_vars` for that image. Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. From e16d4402ce8618e89f4534b4a2406c8c5030f617 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 19:47:29 -0400 Subject: [PATCH 64/73] [Containers] Identify named image Wrangler field --- .../docs/containers/configuration/scheduling-policy/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx index aeb9f4e2ece..0941e165476 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy/index.mdx @@ -130,7 +130,7 @@ this.ctx.container.start({ ### Configure named images -Each key under a `durable_object` application's `containers[].images` configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. When you run `wrangler deploy`, Wrangler builds and uploads that image. You can also set `build_context` and `build_vars` for that image. +Each key under `containers[].images` in your Wrangler configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. When you run `wrangler deploy`, Wrangler builds and uploads that image. You can also set `build_context` and `build_vars` for that image. Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. From b64e3cf9baed8746ba348332027527dea807871f Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:00:48 -0400 Subject: [PATCH 65/73] [Containers] Address review feedback on scheduling policy docs (#33824) - Document SSH support for the durable_object policy and fix the Wrangler configuration and migration guide, which contradicted it - Note that the runtime rejects basic and the dev/standard aliases - Note Cloudflare-registry-only named images, snapshot/image coupling, max_instances, and gradual deployment behavior - Restructure sections, wrap snippets in TypeScriptExample, default examples to enableInternet: false, and flatten the page to a single file Co-authored-by: Claude Opus 5.5 (1M context) --- .../index.mdx => scheduling-policy.mdx} | 50 ++++++++++++------- ...te-to-durable-object-scheduling-policy.mdx | 21 ++++---- .../docs/workers/wrangler/configuration.mdx | 4 ++ 3 files changed, 48 insertions(+), 27 deletions(-) rename src/content/docs/containers/configuration/{scheduling-policy/index.mdx => scheduling-policy.mdx} (74%) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy.mdx similarity index 74% rename from src/content/docs/containers/configuration/scheduling-policy/index.mdx rename to src/content/docs/containers/configuration/scheduling-policy.mdx index 0941e165476..1f874ea36a0 100644 --- a/src/content/docs/containers/configuration/scheduling-policy/index.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy.mdx @@ -10,22 +10,24 @@ products: import { TypeScriptExample, WranglerConfig } from "~/components"; -A scheduling policy determines where you configure a Container image and instance size. It also determines how image updates and [rollouts](/containers/configuration/rollouts/) apply. Choose the policy when you create the Container application. +A scheduling policy determines where you configure a Container image and [instance size](/containers/platform/limits/#instance-types). It also determines how image updates and [rollouts](/containers/configuration/rollouts/) apply. Choose the policy when you create the Container application. + +:::note +The `durable_object` scheduling policy is in public beta. +::: | Policy | Configure image and instance size | Image updates | Best for | | ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | | `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | -The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting and recreating an application also replaces its Container instances. To move an existing application, refer to [Migrate to the Durable Object scheduling policy](/containers/guides/migrate-to-durable-object-scheduling-policy/). +One Wrangler configuration can contain applications with both policies. This lets a Worker use centrally managed service Containers alongside Durable Object-managed sandboxes. -:::note -The `durable_object` scheduling policy is in public beta. -::: +The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting an application also deletes its Container instances, so switching policies means replacing every running instance. To move an existing application, refer to [Migrate to the Durable Object scheduling policy](/containers/guides/migrate-to-durable-object-scheduling-policy/). ## Use the default scheduling policy -With the `default` policy, Wrangler configuration defines one application-wide `image`, one `instance_type`, and settings such as `max_instances`. Omitting `scheduling_policy` selects `default`. +With the `default` policy, Wrangler configuration defines one application-wide `image`, one [`instance_type`](/containers/platform/limits/#instance-types), and settings such as `max_instances`. Omitting `scheduling_policy` selects `default`. @@ -106,7 +108,7 @@ export class AgentComputer extends DurableObject { this.ctx.container.start({ image: this.ctx.container.images.base, instance: "standard-2", - enableInternet: true, + enableInternet: false, }); } } @@ -116,27 +118,33 @@ export class AgentComputer extends DurableObject { `ctx.container.start()` initiates startup and returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic or calling [`exec()`](/containers/api/durable-object-container/#exec). +The `durable_object` policy does not support `max_instances`. Running instances count toward your [account limits](/containers/platform/limits/#account-limits). + ### Use the Cloudflare-managed image If you do not need a custom image, start the [`cloudflare/debian-trixie` Cloudflare-managed image](/containers/guides/image-management/#use-the-cloudflare-managed-image) directly without adding a named image to Wrangler. It includes Node.js 24.20.0 on Debian Trixie slim: -```js + + +```ts this.ctx.container.start({ image: "cloudflare/debian-trixie", instance: "standard-2", - enableInternet: true, + enableInternet: false, }); ``` + + ### Configure named images Each key under `containers[].images` in your Wrangler configuration becomes a property on `ctx.container.images`. For example, `containers[].images.base` is available to the Durable Object as `ctx.container.images.base`. Each value must specify exactly one image source. Use `dockerfile` for a path to a Dockerfile. When you run `wrangler deploy`, Wrangler builds and uploads that image. You can also set `build_context` and `build_vars` for that image. -Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. +Use `image` for a digest-pinned image in the Cloudflare managed registry. Use the form `registry.cloudflare.com//@sha256:`. Direct references to Docker Hub, Amazon ECR, or Google Artifact Registry are not supported. To use an image from another registry, [push it to the Cloudflare managed registry](/containers/guides/image-management/#use-an-external-image) first. A configuration can contain up to 100 named images. An image name must contain between 1 and 128 characters. -The image map is uploaded with the Worker version. Updating the map does not restart or replace running Container instances. Your application selects an image from the map when it starts an instance. +The image map is uploaded with the Worker version. Updating the map does not restart or replace running Container instances. Your application selects an image from the map when it starts an instance. During a [gradual deployment](/workers/versions-and-deployments/gradual-deployments/), `ctx.container.images` reflects the image map of the Worker version that runs the Durable Object, so different Durable Objects can start different images until the deployment completes. ### Choose an instance size at runtime @@ -148,7 +156,11 @@ Set `instance` in `ctx.container.start()` to one of the following [named instanc - `standard-3` - `standard-4` -If you omit `instance`, the Container uses `lite`. You can also supply a custom instance object: +The runtime does not accept `basic` or the legacy `dev` and `standard` aliases. + +If you omit `instance`, the Container uses `lite`. You can also supply a custom instance object that meets the [custom instance type constraints](/containers/platform/limits/#custom-instance-types): + + ```ts this.ctx.container.start({ @@ -162,21 +174,25 @@ this.ctx.container.start({ }); ``` -The runtime uses camel case (`memoryMib` and `diskMb`). Wrangler's application-level `instance_type` object uses snake case (`memory_mib` and `disk_mb`) and only applies to the `default` policy. Refer to [Limits and Instance Types](/containers/platform/limits/). + -### Start from an image or snapshot +The runtime uses camel case (`memoryMib` and `diskMb`). Wrangler's application-level `instance_type` object uses snake case (`memory_mib` and `disk_mb`) and only applies to the `default` policy. -Snapshot creation and restore are only supported for applications that use the `durable_object` scheduling policy. Applications that use the `default` policy cannot create or restore snapshots. +### Start from an image or snapshot For a new filesystem, pass `image` to `ctx.container.start()`. To restore a full filesystem snapshot, pass `containerSnapshot` instead. `image` and `containerSnapshot` are mutually exclusive because a snapshot already identifies the filesystem to restore. +Snapshots are only supported with the `durable_object` policy. A snapshot is tied to the image it was created from. After you update an image, create new snapshots from Containers running that image. + Refer to [Snapshots](/containers/guides/snapshots/) for the complete save and restore flow. ### Manage updates from application code -Container instances that use the `durable_object` policy do not participate in application-wide image rollouts. A running instance continues to use its startup image. Your application decides when to stop that instance and start it with another configured image. +Container instances that use the `durable_object` policy do not participate in application-wide image rollouts. A running instance continues to use its startup image. Your application decides when to stop that instance and start it with another configured image. For an example that compares the running image with the configured image, refer to [Roll out a named image update](/containers/guides/image-management/#roll-out-a-named-image-update). -One Wrangler configuration can contain applications with both policies. This lets a Worker use centrally managed service Containers alongside Durable Object-managed sandboxes. +### Configure SSH + +The `durable_object` policy supports the `ssh` and `authorized_keys` fields. Refer to [SSH](/containers/guides/ssh/). ## Related resources diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx index d5d1f5a69b7..a5c69196a10 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx @@ -31,16 +31,17 @@ If the existing Durable Objects contain data, design an application-specific tra Map the existing application configuration to its `durable_object` equivalent: -| `default` policy | `durable_object` policy | -| -------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| `image` | A named `images` entry, selected with `ctx.container.start()` | -| `image_build_context` | `build_context` on the named image | -| `image_vars` | `build_vars` on the named image | -| `instance_type` | The `instance` option in `ctx.container.start()` | -| Application-wide image rollouts | Application code that stops and starts each Container | -| `observability` | Keep in Wrangler configuration, subject to `durable_object` restrictions | -| `unsafe.configuration.experimental_flags` | Keep in Wrangler configuration | -| `max_instances`, placement constraints, rollout settings, and SSH settings | Not supported on the replacement application | +| `default` policy | `durable_object` policy | +| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `image` | A named `images` entry, selected with `ctx.container.start()` | +| `image_build_context` | `build_context` on the named image | +| `image_vars` | `build_vars` on the named image | +| `instance_type` | The `instance` option in `ctx.container.start()` | +| Application-wide image rollouts | Application code that stops and starts each Container | +| `observability` | Keep in Wrangler configuration, subject to `durable_object` restrictions | +| `unsafe.configuration.experimental_flags` | Keep in Wrangler configuration | +| `ssh` and `authorized_keys` | Keep in Wrangler configuration | +| `max_instances`, placement constraints, rollout settings, `wrangler_ssh`, and `trusted_user_ca_keys` | Not supported on the replacement application | For the complete field compatibility list, refer to [Wrangler configuration](/workers/wrangler/configuration/#containers). diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 8a03c5f2e07..b061560b60e 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -1427,6 +1427,10 @@ A `durable_object` entry accepts only the following options. Wrangler rejects ev - Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. - `unsafe.configuration.experimental_flags` - Experimental application flags. This is the only `unsafe` setting accepted with the `durable_object` policy. +- `ssh` + - Configuration for SSH through Wrangler. Refer to [SSH](#ssh). The deprecated `wrangler_ssh` alias is not accepted with the `durable_object` policy. +- `authorized_keys` + - Public keys that should be added to the Container's `authorized_keys` file. Refer to [Authorized keys](#authorized-keys). Name one or more images and select one from Durable Object code when the Container starts: From cee86a6cf25ad63661f38b4ac0be4478a84c8e25 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 20:03:36 -0400 Subject: [PATCH 66/73] [Containers] Label Durable Object policy beta --- .../containers/configuration/scheduling-policy.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/content/docs/containers/configuration/scheduling-policy.mdx b/src/content/docs/containers/configuration/scheduling-policy.mdx index 1f874ea36a0..9cf6f1baf83 100644 --- a/src/content/docs/containers/configuration/scheduling-policy.mdx +++ b/src/content/docs/containers/configuration/scheduling-policy.mdx @@ -12,15 +12,15 @@ import { TypeScriptExample, WranglerConfig } from "~/components"; A scheduling policy determines where you configure a Container image and [instance size](/containers/platform/limits/#instance-types). It also determines how image updates and [rollouts](/containers/configuration/rollouts/) apply. Choose the policy when you create the Container application. +| Policy | Configure image and instance size | Image updates | Best for | +| ----------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | +| `durable_object` (beta) | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | + :::note The `durable_object` scheduling policy is in public beta. ::: -| Policy | Configure image and instance size | Image updates | Best for | -| ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -| `default` | In Wrangler configuration | Cloudflare applies application-wide configuration changes with [rollouts](/containers/configuration/rollouts/) | Services whose instances use the same image and instance size | -| `durable_object` | In Durable Object code when calling `ctx.container.start()` | Application code selects an image each time it starts an instance | Sandboxes, agent environments, and other workloads that need per-instance configuration | - One Wrangler configuration can contain applications with both policies. This lets a Worker use centrally managed service Containers alongside Durable Object-managed sandboxes. The scheduling policy is immutable. To use a different policy, create a new Container application. Deleting an application also deletes its Container instances, so switching policies means replacing every running instance. To move an existing application, refer to [Migrate to the Durable Object scheduling policy](/containers/guides/migrate-to-durable-object-scheduling-policy/). From 77a34e81bf04daae712df5f3abbe2fe58ff84070 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:20:39 -0400 Subject: [PATCH 67/73] [Wrangler] Review fixes for Containers scheduling policy config reference (#33826) * [Wrangler] Tighten Containers scheduling policy config reference - Document exports..container in the Exports field list and link to it - Clarify custom instance types for the durable_object policy - Mark durable_object as beta and note the SQLite requirement - List named image fields individually with defaults - Align MetaInfo labels, heading case, and registry naming Co-Authored-By: Claude Opus 5.5 (1M context) * Note default value for scheduling_policy in example Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- .../docs/workers/wrangler/configuration.mdx | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index b061560b60e..7f07b0d9d8e 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -631,6 +631,8 @@ Each entry in `exports` is keyed by Durable Object class name. The fields on eac - Required when `state` is `"transferred"`. The name of the target Worker that will receive the namespace. - `transfer_from` - Required when `state` is `"expecting-transfer"`. The name of the source Worker the namespace is being transferred from. +- `container` + - Attaches a [Container](#containers) to this Durable Object. Must match the `name` of an entry in the top-level `containers` array, and requires `storage` to be `"sqlite"`. Only allowed when `state` is `"created"` or `"expecting-transfer"`. Use this instead of setting `class_name` on the Container entry. Example: @@ -1312,7 +1314,7 @@ You can define [Containers](/containers) to run alongside your Worker using the Each Container application has a [scheduling policy](/containers/configuration/scheduling-policy/) that determines whether image and instance configuration is managed centrally or supplied by Durable Object code at runtime. The policy is immutable after the application is created. :::note -Each Container application must link to a Durable Object defined in the same Worker. Set `class_name` on the Container entry, or set `name` and reference that name from [`exports..container`](/durable-objects/reference/durable-objects-migrations/). Configure exactly one of these linkage directions. +Each Container application must link to a Durable Object defined in the same Worker. Set `class_name` on the Container entry, or set `name` and reference that name from [`exports..container`](#exports). Configure exactly one of these linkage directions. ::: ### `default` scheduling policy @@ -1326,17 +1328,17 @@ The following options are available: - `image` - The image to use for the container. This can either be a local path to a `Dockerfile`, in which case `wrangler deploy` will build and push the image, or it can be an image reference. Supported registries are the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry. For more information, refer to [Image Management](/containers/guides/image-management/). -- `class_name` +- `class_name` - The corresponding Durable Object class name. This will make this Durable Object a container-enabled Durable Object and allow each instance to control a container. Refer to the [Durable Object Container API](/containers/api/durable-object-container/) for details. - Omit this field when the Container is linked by `name` from `exports..container`. -- `name` +- `name` - The name of your container. Used as an identifier. This will default to a combination of your Worker name, the class name, and your environment. - Required when `class_name` is omitted so that `exports..container` can reference the Container. - `instance_type` - The instance type determines the amount of memory, CPU, and disk given to the container instance. Supported values are `"lite"`, `"basic"`, `"standard-1"`, `"standard-2"`, `"standard-3"`, and `"standard-4"`. The default is `"lite"`. For more information, refer to [Limits and Instance Types](/containers/platform/limits/#instance-types). - - To specify a custom instance type, see [Custom instance types](#custom-instance-types). + - To specify a custom instance type, refer to [Custom instance types](#custom-instance-types). - `max_instances` - The maximum number of concurrent container instances. Stopped containers do not count towards this - you may have more container instances than this number overall, but only this many actively running containers at once. If a request to start a container will exceed this limit, that request will error. - Defaults to 20. @@ -1373,7 +1375,7 @@ The following options are available: "containers": [ { "class_name": "MyContainer", - "scheduling_policy": "default", + "scheduling_policy": "default", // Optional, defaults to "default". Cannot be changed after the application is created. "image": "./Dockerfile", "max_instances": 10, "instance_type": "basic", // Optional, defaults to "lite" @@ -1407,22 +1409,30 @@ The following options are available: ### `durable_object` scheduling policy -The `durable_object` policy lets each Durable Object supply its Container image or snapshot and instance size to `ctx.container.start()`. Set `scheduling_policy` to `"durable_object"` explicitly. +The `durable_object` policy is in beta. It lets each Durable Object supply its Container image or snapshot and instance size to `ctx.container.start()`. Set `scheduling_policy` to `"durable_object"` explicitly. The linked Durable Object must use SQLite storage. -A `durable_object` entry accepts only the following options. Wrangler rejects every other Container application field for this policy. +A `durable_object` entry accepts only the following options. Wrangler rejects every other Container application field for this policy, including `image`, `instance_type`, `max_instances`, rollout settings, and placement constraints. - `scheduling_policy` - Must be set to `"durable_object"`. - `images` - Named images that Durable Object code can access through `ctx.container.images`. A configuration can contain up to 100 named images, and each name must contain 1-128 characters. - - Each named image must set exactly one of `dockerfile` or `image`. `dockerfile` is a local Dockerfile path and can also set `build_context` and `build_vars`. `image` must be a digest-pinned reference in the Cloudflare managed registry. -- `class_name` + - Each named image must set exactly one of `dockerfile` or `image`. +- `images..dockerfile` + - Path to a local Dockerfile. `wrangler deploy` builds and pushes the image. +- `images..build_context` + - Build context, relative to the Wrangler configuration file. Defaults to the directory of `dockerfile`. Only valid with `dockerfile`. Equivalent to `image_build_context` in the `default` policy. +- `images..build_vars` + - Build-time variables, equivalent to `image_vars` in the `default` policy. Only valid with `dockerfile`. +- `images..image` + - A digest-pinned image reference in the Cloudflare Registry. +- `class_name` - The corresponding Durable Object class name. - Omit this field when the Container is linked by `name` from `exports..container`. -- `name` - - The name of the Container application. +- `name` + - The name of the Container application. Defaults to a combination of your Worker name and the class name. - Required when `class_name` is omitted so that `exports..container` can reference the Container. -- `observability` +- `observability` - Set either `observability.enabled` or `observability.logs.enabled` to enable or disable application-wide Container logs. - Instance targeting with `target_instance_count` or `target_instance_percentage` is not supported. If you omit `observability`, Wrangler preserves the application's existing setting instead of inheriting the root Worker setting. - `unsafe.configuration.experimental_flags` @@ -1472,11 +1482,13 @@ Name one or more images and select one from Durable Object code when the Contain -Configure the startup image or snapshot and instance size in `ctx.container.start()`. Fields from the `default` policy, including `image`, `instance_type`, `max_instances`, rollout settings, and placement constraints, are not supported. +Configure the startup image or snapshot and instance size in `ctx.container.start()`. Refer to [Scheduling policy](/containers/configuration/scheduling-policy/) for a code example. + +### Custom instance types -### Custom Instance Types +In Wrangler configuration, custom instance types apply only to the `default` scheduling policy. With the `durable_object` policy, pass a custom instance object to `ctx.container.start()` instead. Refer to [Scheduling policy](/containers/configuration/scheduling-policy/). -Custom instance types only apply to the `default` scheduling policy. In place of the [named instance types](/containers/platform/limits/#instance-types), you can set a custom instance type by individually configuring vCPU, memory, and disk. +In place of the [named instance types](/containers/platform/limits/#instance-types), you can set a custom instance type by individually configuring vCPU, memory, and disk. See the [limits documentation](/containers/platform/limits/#custom-instance-types) for constraints on custom instance types. The following options are available: @@ -1511,7 +1523,7 @@ The following options are available: ### SSH -SSH configuration applies to both the `default` and `durable_object` scheduling policies. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). +Configuration for SSH access to a Container instance through Wrangler. SSH configuration applies to both the `default` and `durable_object` scheduling policies. For a guide on connecting to Containers via SSH, refer to [SSH](/containers/guides/ssh/). The following options are available: From 921e4e4942a9bc54607bf8bf232c44cf8971ccee Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:29:20 -0400 Subject: [PATCH 68/73] [Containers] Image management review fixes for #33531 (#33828) * [Containers] Address image management review feedback - Replace the inspect()-based upgrade example with one that records the started image in Durable Object storage, and warn that destroy() loses filesystem state. - Note gradual deployment behavior when rolling out named image updates. - Add a step for getting the digest of a pushed image, and move the registry push and CI sections out of the default-policy section. - Make enableInternet consistent, align on "digest-pinned reference", and restore registry names in the page description. Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Keep original image management description Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Clarify Workers gradual deployment link text Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Simplify image upgrade example Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Clarify external registry support by scheduling policy Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- .../containers/guides/image-management.mdx | 89 ++++++++++++++----- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index c5464889859..3414e22a867 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -70,7 +70,7 @@ The following configuration defines one image from each source: -Wrangler builds or resolves each named image and exposes its immutable reference through `ctx.container.images`. Select a reference when the Durable Object starts its Container: +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: @@ -94,7 +94,7 @@ A configuration can contain up to 100 named images. Each image name must contain ### 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. The corresponding value in `ctx.container.images` now refers to the updated image. +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](/workers/versions-and-deployments/gradual-deployments/), 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. @@ -107,40 +107,47 @@ if (!this.ctx.container.running) { this.ctx.container.start({ image: this.ctx.container.images.base, instance: "standard-2", - enableInternet: true, + enableInternet: false, }); } ``` -To upgrade a running Container immediately, compare its current image with the configured image. Stop and restart the Container when they differ: +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: ```ts -if ((await this.ctx.container.inspect())?.image !== this.ctx.container.images.base) { - if (this.ctx.container.running) { - await this.ctx.container.destroy(); - } +const image = this.ctx.container.images.base; +const info = await this.ctx.container.inspect(); + +if (info && info.image !== image) { + await this.ctx.container.destroy(); +} +if (!this.ctx.container.running) { this.ctx.container.start({ - image: this.ctx.container.images.base, + image, instance: "standard-2", - enableInternet: true, + 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](/containers/guides/snapshots/) 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](#use-images-from-other-registries). Then, configure the resulting digest-pinned reference as a named image. +To use an image from another registry, pull it and [push it to the Cloudflare managed registry](#use-images-from-other-registries). Then, [get its digest](#get-the-digest-of-a-pushed-image) 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. @@ -181,7 +188,7 @@ This is not necessary if you are using a pre-built image, as described below. ### Use pre-built container images -Containers support images from the Cloudflare managed registry at `registry.cloudflare.com`, [Docker Hub](https://hub.docker.com/), [Amazon ECR](https://aws.amazon.com/ecr/), and [Google Artifact Registry](https://cloud.google.com/artifact-registry). +With the `default` scheduling policy, Containers support images from the Cloudflare managed registry at `registry.cloudflare.com`, [Docker Hub](https://hub.docker.com/), [Amazon ECR](https://aws.amazon.com/ecr/), and [Google Artifact Registry](https://cloud.google.com/artifact-registry). :::note Cloudflare does not cache images pulled from Docker Hub, Amazon ECR, or Google Artifact Registry. @@ -189,6 +196,10 @@ Cloudflare does not cache images pulled from Docker Hub, Amazon ECR, or Google A 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-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. @@ -390,7 +401,21 @@ image = "-docker.pkg.dev///:" -#### Use images from other registries +To use an image from a registry not listed above, [push it to the Cloudflare Registry](#use-images-from-other-registries). + +:::note +With `wrangler dev`, image references from the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry are supported in local development. + +With `vite dev`, image references from external registries such as Docker Hub, Amazon ECR, and Google Artifact Registry are supported, but `vite dev` cannot pull directly from the Cloudflare Registry. + +If you use a private Docker Hub, Amazon ECR, or Google Artifact Registry image in local development, authenticate to that registry locally, for example with `docker login`. +::: + +## Push images to the Cloudflare Registry + +Both scheduling policies can use images that you push to the Cloudflare Registry yourself. With the `durable_object` policy, this is required for any image from Docker Hub, Amazon ECR, Google Artifact Registry, or another external registry. + +### Use images from other registries If you want to use a pre-built image from another registry provider, first make sure it exists locally, then push it to the Cloudflare Registry: @@ -415,7 +440,7 @@ Or, you can use the `-p` flag with `wrangler containers build` to build and push args="containers build -p -t ." /> -This will output an image registry URI that you can then use in your Wrangler configuration: +This will output an image registry URI. With the `default` scheduling policy, you can use this tag reference in your Wrangler configuration: @@ -431,19 +456,43 @@ This will output an image registry URI that you can then use in your Wrangler co -:::note -With `wrangler dev`, image references from the Cloudflare Registry, Docker Hub, Amazon ECR, and Google Artifact Registry are supported in local development. +With the `durable_object` scheduling policy, a named `image` source requires a digest-pinned reference. [Get the digest of the pushed image](#get-the-digest-of-a-pushed-image) first. -With `vite dev`, image references from external registries such as Docker Hub, Amazon ECR, and Google Artifact Registry are supported, but `vite dev` cannot pull directly from the Cloudflare Registry. +### Get the digest of a pushed image -If you use a private Docker Hub, Amazon ECR, or Google Artifact Registry image in local development, authenticate to that registry locally, for example with `docker login`. -::: +After you push an image, list its repository digests with Docker: + +```bash +docker image inspect --format '{{join .RepoDigests "\n"}}' registry.cloudflare.com//: +``` + +Use the entry that starts with `registry.cloudflare.com/` as a named `image` source: + + + +```jsonc +{ + "containers": [ + { + "class_name": "AgentComputer", + "scheduling_policy": "durable_object", + "images": { + "tools": { + "image": "registry.cloudflare.com//@sha256:", + }, + }, + }, + ], +} +``` + + ### Push images with CI To use an image built in a continuous integration environment, install `wrangler` then build and push images using either `wrangler containers build` with the `--push` flag, or -using the `wrangler containers push` command. +using the `wrangler containers push` command. With the `durable_object` scheduling policy, [get the digest of the pushed image](#get-the-digest-of-a-pushed-image) before you update your Wrangler configuration. ## Registry limits From 54f1bfaf6c9dd4866de41d12a1d2d215ee8902a1 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:46:53 -0400 Subject: [PATCH 69/73] [Containers] Fix DO Container API examples and inspect() image docs (#33825) - Pass start() options in the intro and monitor() examples so they work with the durable_object scheduling policy - Document that inspect() reports an empty image for a container restored from a snapshot (cloudchamberd passes no image ref) - Keep restored Containers running in the image upgrade example, which destroyed every snapshot-restored Container - Move scheduling-policy.mdx back to scheduling-policy/index.mdx so the nested move-from-default page in #33767 does not conflict Co-authored-by: Claude Opus 5.5 (1M context) --- .../containers/api/durable-object-container.mdx | 14 +++++++++++--- .../index.mdx} | 0 .../docs/containers/guides/image-management.mdx | 6 ++++-- 3 files changed, 15 insertions(+), 5 deletions(-) rename src/content/docs/containers/configuration/{scheduling-policy.mdx => scheduling-policy/index.mdx} (100%) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index c946749c042..78a055334d9 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -35,7 +35,11 @@ export class MyDurableObject extends DurableObject { throw new Error("No container is configured for this Durable Object"); } if (!container.running) { - container.start(); + // With the `default` scheduling policy, call `container.start()` without options. + container.start({ + image: container.images.base, + enableInternet: false, + }); await this.ctx.storage.put("lastStartedAt", Date.now()); } } @@ -124,7 +128,7 @@ const containerInfo = await this.ctx.container.inspect(); #### Return values - `Promise`: Resolves with `null` when no container is running. Otherwise, it resolves with a `ContainerInfo` object containing: - - `image` (`string`): Image reference reported by the runtime. The value can be an empty string. + - `image` (`string`): Image reference passed to [`start()`](#start). The value is an empty string for a container restored from `containerSnapshot`. - `labels` (`Record`): Labels passed to [`start()`](#start). ### `exec` @@ -340,7 +344,11 @@ interface Env {} class MyDurableObject extends DurableObject { startAndMonitor() { const container = this.ctx.container; - container.start(); + // With the `default` scheduling policy, call `container.start()` without options. + container.start({ + image: container.images.base, + enableInternet: false, + }); this.ctx.waitUntil( container .monitor() diff --git a/src/content/docs/containers/configuration/scheduling-policy.mdx b/src/content/docs/containers/configuration/scheduling-policy/index.mdx similarity index 100% rename from src/content/docs/containers/configuration/scheduling-policy.mdx rename to src/content/docs/containers/configuration/scheduling-policy/index.mdx diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 3414e22a867..8be03ec069e 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -114,7 +114,9 @@ if (!this.ctx.container.running) { -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: +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. + +A Container restored from a snapshot reports an empty image from `inspect()`. The following example keeps restored Containers running instead of replacing them: @@ -122,7 +124,7 @@ To upgrade a running Container immediately, compare its image with the configure const image = this.ctx.container.images.base; const info = await this.ctx.container.inspect(); -if (info && info.image !== image) { +if (info && info.image !== "" && info.image !== image) { await this.ctx.container.destroy(); } From db5cfb2a7efac2306fe6afef5c7bb9aa664ab394 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:50:54 -0400 Subject: [PATCH 70/73] [Containers] Review fixes for scheduling policy migration guide (#33827) * [Containers] Address review feedback on scheduling policy migration guide - Add prerequisites: Container class is unsupported with durable_object, exports/migrations are mutually exclusive, external images must move to the Cloudflare managed registry. - Split image row by source; call out max_instances replacement. - Add instance size mapping (basic/dev/standard, camel-case custom sizes). - Keep the existing Container entry unchanged in the example config. - Match existing enableInternet behavior in the startup example. - Warn against per-request cutover that can run one sandbox twice. - Merge steps 1 and 2; clarify validation and cleanup wording. Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Clarify replacement app requirement in migration guide - Lead step 1 with why a new class and Container application are required. - Warn against changing scheduling_policy in place: wrangler deploy ships the Worker version before configuring the Container application, so the deploy fails with the new code already live. - List the three required additions explicitly. - Explain what the `instance` option is before listing accepted values. Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- ...te-to-durable-object-scheduling-policy.mdx | 105 ++++++++++++------ 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx index a5c69196a10..c88683478d8 100644 --- a/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx +++ b/src/content/docs/containers/guides/migrate-to-durable-object-scheduling-policy.mdx @@ -21,43 +21,69 @@ The replacement application must use a new Durable Object class and namespace. T :::caution -This process does not transfer existing Container instances, their filesystems, or Durable Object storage. The `default` scheduling policy does not support snapshots, so you cannot use a Container snapshot to transfer its filesystem. +This process does not transfer existing Container instances or Durable Object storage. The `default` scheduling policy does not support snapshots, so you cannot use a Container snapshot to transfer a filesystem. If the existing Durable Objects contain data, design an application-specific transfer process before continuing. ::: +## Before you begin + +- **Replace the `Container` class.** The [`Container` class](/containers/api/container-class/) does not support the `durable_object` policy. If your existing class extends `Container`, the replacement class must use the [Durable Object Container API](/containers/api/durable-object-container/) directly. Rebuild any `Container` class helpers your application relies on, such as port readiness checks, request proxying, and sleep timeouts. Refer to [Migrate to the Durable Object Container API](/containers/guides/migrate-to-durable-object-container-api/). +- **Check how the Worker declares Durable Object classes.** A Worker uses either the [`exports` field](/durable-objects/reference/durable-objects-migrations/) or the [legacy `migrations` array](/durable-objects/reference/durable-object-class-migrations-legacy/), not both. Declare the replacement class with the same mechanism the Worker already uses. Moving from `migrations` to `exports` cannot be undone. If you want to move, do it as a separate change. Refer to [Migrate from the legacy `migrations` flow](/durable-objects/reference/durable-objects-migrations/#migrate-from-the-legacy-migrations-flow). +- **Move external images to the Cloudflare managed registry.** Named images with the `durable_object` policy must use a Dockerfile or a digest-pinned reference in the Cloudflare managed registry. If the existing `image` references Docker Hub, Amazon ECR, or Google Artifact Registry, [push the image to the Cloudflare managed registry](/containers/guides/image-management/#use-an-external-image) first. + ## Configuration changes Map the existing application configuration to its `durable_object` equivalent: -| `default` policy | `durable_object` policy | -| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| `image` | A named `images` entry, selected with `ctx.container.start()` | -| `image_build_context` | `build_context` on the named image | -| `image_vars` | `build_vars` on the named image | -| `instance_type` | The `instance` option in `ctx.container.start()` | -| Application-wide image rollouts | Application code that stops and starts each Container | -| `observability` | Keep in Wrangler configuration, subject to `durable_object` restrictions | -| `unsafe.configuration.experimental_flags` | Keep in Wrangler configuration | -| `ssh` and `authorized_keys` | Keep in Wrangler configuration | -| `max_instances`, placement constraints, rollout settings, `wrangler_ssh`, and `trusted_user_ca_keys` | Not supported on the replacement application | +| `default` policy | `durable_object` policy | +| ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `image` (Dockerfile path) | `dockerfile` on a named `images` entry, selected with `ctx.container.start()` | +| `image` (registry reference) | `image` on a named `images` entry. Must be a digest-pinned reference in the Cloudflare managed registry | +| `image_build_context` | `build_context` on the named image | +| `image_vars` | `build_vars` on the named image | +| `instance_type` | The `instance` option in `ctx.container.start()`. Refer to [Instance size changes](#instance-size-changes) | +| `max_instances` | Not supported. Running instances count toward [account limits](/containers/platform/limits/#account-limits). Enforce any per-application cap in application code | +| Application-wide image rollouts | Application code that stops and starts each Container | +| `observability` | Keep in Wrangler configuration, subject to `durable_object` restrictions | +| `unsafe.configuration.experimental_flags` | Keep in Wrangler configuration | +| `ssh` and `authorized_keys` | Keep in Wrangler configuration | +| Placement constraints, rollout settings, `wrangler_ssh`, and `trusted_user_ca_keys` | Not supported on the replacement application | For the complete field compatibility list, refer to [Wrangler configuration](/workers/wrangler/configuration/#containers). +### Instance size changes + +With the `durable_object` policy, you set the instance size with the `instance` option of `ctx.container.start()` instead of `instance_type` in Wrangler configuration. `instance` accepts `lite`, `standard-1`, `standard-2`, `standard-3`, and `standard-4`. If your existing application uses one of the following `instance_type` values, choose a replacement: + +- `dev`: Use `lite`. +- `standard`: Use `standard-1`. +- `basic`: Choose `lite` or `standard-1`. Custom instance types require at least 1 vCPU, so you cannot reproduce `basic` with a custom instance. + +Custom instance objects use camel case at runtime. Rename `memory_mib` to `memoryMib` and `disk_mb` to `diskMb`. Refer to [Choose an instance size at runtime](/containers/configuration/scheduling-policy/#choose-an-instance-size-at-runtime). + ## Move the application -1. **Create a replacement Durable Object class.** +1. **Add a new Durable Object class and Container application.** + + You cannot move the existing application by changing its `scheduling_policy` to `durable_object`, because the scheduling policy cannot be changed after creation. You also cannot reuse the existing Durable Object class, because each Durable Object namespace attaches to one Container application. - Add a new SQLite-backed Durable Object class and binding. Keep the existing class and binding so that you can route traffic back to them. + :::caution + Do not change `scheduling_policy` on the existing Container entry. `wrangler deploy` deploys the new Worker version before it configures the Container application. The deploy then fails with the new Worker code already live and no `durable_object` application behind it. + ::: - Use the declarative `exports` field to define both SQLite-backed Durable Object classes. Keep the existing class exported while you add the replacement class. + Instead, add all of the following to the Wrangler configuration: -2. **Add a replacement Container application.** + - A new SQLite-backed Durable Object class. + - A Durable Object binding for the new class. + - A new Container entry with `"scheduling_policy": "durable_object"`, a different `name`, and `class_name` set to the new class. - Keep the existing application and add a differently named application with the `durable_object` policy: + Leave the existing Container entry, Durable Object class, and binding unchanged so that you can route traffic back to them. Changing the existing entry's `name` or `class_name` can cause Wrangler to create a new application instead of updating the existing one. + + The following example uses `exports`. If the Worker uses the legacy `migrations` array, add a new migration with `new_sqlite_classes: ["DurableSandbox"]` instead. @@ -67,14 +93,14 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo "main": "src/index.ts", "compatibility_date": "2026-09-29", "containers": [ + // Existing application. Keep this entry unchanged. { - "name": "sandbox-default", - "class_name": "LegacySandbox", - "scheduling_policy": "default", + "class_name": "Sandbox", "image": "./container/Dockerfile", "instance_type": "standard-2", "max_instances": 10, }, + // Replacement application. { "name": "sandbox-durable-object", "class_name": "DurableSandbox", @@ -89,8 +115,8 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo "durable_objects": { "bindings": [ { - "name": "LEGACY_SANDBOX", - "class_name": "LegacySandbox", + "name": "SANDBOX", + "class_name": "Sandbox", }, { "name": "DURABLE_SANDBOX", @@ -99,7 +125,7 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo ], }, "exports": { - "LegacySandbox": { + "Sandbox": { "type": "durable-object", "storage": "sqlite", }, @@ -113,7 +139,7 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo -3. **Move startup configuration into the replacement class.** +2. **Move startup configuration into the replacement class.** Select the image and instance size when the replacement Durable Object starts its Container: @@ -131,7 +157,8 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo this.ctx.container.start({ image: this.ctx.container.images.base, instance: "standard-2", - enableInternet: false, + // Match the existing application's outbound access. + enableInternet: true, }); } } @@ -139,40 +166,43 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo - Move other supported startup settings, such as `env`, `entrypoint`, and `enableInternet`, into the same call. Add an application-specific readiness check before sending traffic to the Container. + Move other supported startup settings, such as `env` and `entrypoint`, into the same call. Set `enableInternet` to match the existing application. The `Container` class allows outbound Internet access unless you set `enableInternet = false`. + + `ctx.container.start()` returns before the Container is ready to accept requests. Add an application-specific readiness check before sending traffic to the Container. -4. **Deploy and validate the replacement application.** +3. **Deploy and validate the replacement application.** Deploy both applications: - Start a replacement Container without changing production routing. Confirm that the image, instance size, environment, entrypoint, network access, and readiness behavior match the existing application. + Start a replacement Container without changing production routing, for example through a test-only route that uses the `DURABLE_SANDBOX` binding. Confirm that the image, instance size, environment, entrypoint, network access, and readiness behavior match the existing application. -5. **Cut traffic over to the replacement namespace.** +4. **Cut traffic over to the replacement namespace.** - Update the Worker routing logic to resolve Container IDs through the replacement Durable Object binding. New Durable Object IDs refer to the replacement namespace and do not access storage from the old namespace. + Update the Worker routing logic to resolve Container IDs through the replacement Durable Object binding. The same name resolves to a different Durable Object in each namespace. A Durable Object in the replacement namespace cannot access storage from the old namespace. - For example, you can use a feature flag to select the binding while keeping the same logical name: + Choose the binding per logical Container, not per request. If requests for the same name can reach both bindings, such as during a percentage-based rollout or a [gradual deployment](/workers/versions-and-deployments/gradual-deployments/), two Containers can run for one logical sandbox and their state can diverge. For example, record which namespace each sandbox uses and read that record when routing: ```ts - const binding = useReplacement + // isMigrated() is application code that reads a per-sandbox record. + const binding = (await isMigrated(sandboxName)) ? env.DURABLE_SANDBOX - : env.LEGACY_SANDBOX; + : env.SANDBOX; const sandbox = binding.getByName(sandboxName); ``` - If Durable Object state must move, complete the application-specific transfer before routing all traffic to the replacement namespace. + If Durable Object state must move, complete the application-specific transfer for each sandbox before routing it to the replacement namespace. -6. **Observe the replacement application.** +5. **Observe the replacement application.** Keep the old application, class, and binding during the observation period. To roll back, route traffic to the old Durable Object binding again. Writes made after cutover stay in the replacement namespace. If the application accepts writes, plan how to reconcile that data before rolling back. -7. **Delete the old Container application.** +6. **Delete the old Container application.** - After the rollback period, remove the old Container entry and routing code from the Worker configuration. Deploy the updated Worker. Keep the old Durable Object class and binding until you no longer need its stored data. + After the rollback period, remove the old Container entry from the Wrangler configuration and the old routing path from the Worker code. Deploy the updated Worker. Keep the old Durable Object class and binding until you no longer need its stored data. Removing the entry from Wrangler configuration does not delete the existing Container application. List the applications and copy the old application ID: @@ -193,3 +223,4 @@ For the complete field compatibility list, refer to [Wrangler configuration](/wo - [Scheduling Policies](/containers/configuration/scheduling-policy/) - [Image Management](/containers/guides/image-management/) - [Durable Object Container API](/containers/api/durable-object-container/) +- [Migrate to the Durable Object Container API](/containers/guides/migrate-to-durable-object-container-api/) From 33f4f338165b0fee41a4717ebc73fe215c9eb3ce Mon Sep 17 00:00:00 2001 From: Thomas Gauvin <35609369+thomasgauvin@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:58:31 -0400 Subject: [PATCH 71/73] [Containers] Clarify when inspect() reports an empty image (#33830) * [Containers] Fix image docs based on end-to-end testing - Document that inspect() reports an empty image while a container is starting, not only after a snapshot restore. - Add a long-running entrypoint to cloudflare/debian-trixie examples, whose default node command exits immediately. - Note the Unsupported platform error when pushing pulled multi-platform images with the containerd image store. Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Drop managed image entrypoint change Co-Authored-By: Claude Opus 5.5 (1M context) * [Containers] Drop containerd platform note Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- src/content/docs/containers/api/durable-object-container.mdx | 2 +- src/content/docs/containers/guides/image-management.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/api/durable-object-container.mdx b/src/content/docs/containers/api/durable-object-container.mdx index 78a055334d9..8f856aee758 100644 --- a/src/content/docs/containers/api/durable-object-container.mdx +++ b/src/content/docs/containers/api/durable-object-container.mdx @@ -128,7 +128,7 @@ const containerInfo = await this.ctx.container.inspect(); #### Return values - `Promise`: Resolves with `null` when no container is running. Otherwise, it resolves with a `ContainerInfo` object containing: - - `image` (`string`): Image reference passed to [`start()`](#start). The value is an empty string for a container restored from `containerSnapshot`. + - `image` (`string`): Image reference passed to [`start()`](#start). The value is an empty string while the container is starting and for a container restored from `containerSnapshot`. - `labels` (`Record`): Labels passed to [`start()`](#start). ### `exec` diff --git a/src/content/docs/containers/guides/image-management.mdx b/src/content/docs/containers/guides/image-management.mdx index 8be03ec069e..04aa7a6f6a0 100644 --- a/src/content/docs/containers/guides/image-management.mdx +++ b/src/content/docs/containers/guides/image-management.mdx @@ -116,7 +116,7 @@ if (!this.ctx.container.running) { 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. -A Container restored from a snapshot reports an empty image from `inspect()`. The following example keeps restored Containers running instead of replacing them: +`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: From cc4f9e101624bea8413260935b2f5fedce3f4dc2 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 21:01:18 -0400 Subject: [PATCH 72/73] [Containers] Document snapshot limits --- src/content/docs/containers/guides/snapshots.mdx | 2 +- src/content/docs/containers/platform/limits.mdx | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/content/docs/containers/guides/snapshots.mdx b/src/content/docs/containers/guides/snapshots.mdx index edadfd0651a..913c5e0b972 100644 --- a/src/content/docs/containers/guides/snapshots.mdx +++ b/src/content/docs/containers/guides/snapshots.mdx @@ -69,7 +69,7 @@ export class MyDurableObject extends DurableObject { ## Understand retention -Snapshots have an implicit 30-day time-to-live. Each restore refreshes that time-to-live. +Snapshots have an implicit [30-day time-to-live](/containers/platform/limits/#snapshot-limits). Each restore refreshes that time-to-live. You cannot set a custom time-to-live yet. diff --git a/src/content/docs/containers/platform/limits.mdx b/src/content/docs/containers/platform/limits.mdx index 235409ac19d..6f4f0ce0b84 100644 --- a/src/content/docs/containers/platform/limits.mdx +++ b/src/content/docs/containers/platform/limits.mdx @@ -1,7 +1,7 @@ --- pcx_content_type: reference title: Limits and Instance Types -description: Available Container instance types and account-level limits for memory, vCPU, disk, and image storage. +description: Available Container instance types and limits for memory, vCPU, disk, image storage, and snapshots. sidebar: order: 1 products: @@ -56,3 +56,14 @@ The following limits apply per account: | Total image storage per account | 50 GB [^1] | [^1]: Delete container images with `wrangler containers delete` to free up space. If you delete a container image and then [roll back](/workers/versions-and-deployments/rollbacks/) your Worker to a previous version, this version may no longer work. + +## Snapshot limits + +The following limits apply to [Container snapshots](/containers/guides/snapshots/): + +| Resource | Limit | +| --------------------- | ----------------------------------------------- | +| Maximum snapshot size | 20 GB | +| Snapshot retention | 30 days from creation or the most recent restore | + +Restoring a snapshot refreshes its 30-day time-to-live. From 1a126cc740aef1eb2fd1b90d47fe83c608a507a1 Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Tue, 29 Sep 2026 21:33:34 -0400 Subject: [PATCH 73/73] [Containers] Restore flat scheduling policy path --- .../{scheduling-policy/index.mdx => scheduling-policy.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/content/docs/containers/configuration/{scheduling-policy/index.mdx => scheduling-policy.mdx} (100%) diff --git a/src/content/docs/containers/configuration/scheduling-policy/index.mdx b/src/content/docs/containers/configuration/scheduling-policy.mdx similarity index 100% rename from src/content/docs/containers/configuration/scheduling-policy/index.mdx rename to src/content/docs/containers/configuration/scheduling-policy.mdx