Containers provide two APIs for managing a container from a Durable Object. Both APIs address the same container runtime.
For new applications, we recommend the Durable Object Container API. It lets you combine container workloads with the Durable Object's persistent storage, alarms, and request handling. Use ctx.container to control the container lifecycle while your Durable Object coordinates application state. The Container class remains documented for existing applications.
Durable Object Container API
Start, stop, monitor, and connect to a container through ctx.container.
Container class
Reference the class and its routing, readiness checks, lifecycle hooks, and scheduling for existing applications.
Inside a Durable Object, use ctx.container to control the container runtime directly. You can manage startup, shutdown, networking, and resource usage while using Durable Object storage and alarms for state and coordination. Add readiness checks, custom request routing, or lifecycle policies when needed.
The Container class extends DurableObject and wraps the container runtime API with convenience methods. Existing applications can use these methods for request proxying, readiness checks, lifecycle hooks, and scheduling. Durable Object storage and alarms remain available when needed.
The following examples compare the starting structure for each API:
import { DurableObject } from "cloudflare:workers";
interface Env {}
export class MyContainer extends DurableObject<Env> {
fetch(): Response {
const container = this.ctx.container;
if (!container) {
return new Response("No container is configured", { status: 500 });
}
if (container.running) {
return new Response("Container is running");
}
container.start();
return new Response("Container is starting", { status: 202 });
}
}import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
sleepAfter = "10m";
}Starting a container through the Durable Object Container API does not mean its ports are ready. For request routing, use getTcpPort() after checking port readiness. For all direct methods, refer to the Durable Object Container API. For convenience methods, refer to the Container class API.
The following table compares both options:
| Requirement | Durable Object Container API | Container class |
|---|---|---|
| Start and stop a container | start(), signal(), and destroy() |
start(), stop(), and destroy() |
| Send and proxy traffic | getTcpPort(port).fetch() and getTcpPort(port).connect() |
fetch() and containerFetch() |
| Execute another process | exec() |
ctx.container.exec() |
| Check port readiness | Use getTcpPort() in application code |
startAndWaitForPorts() and waitForPort() |
| Handle concurrent starts | Coordinate calls to start() when needed |
Handled by start() and startAndWaitForPorts() |
| Run lifecycle hooks | monitor() and application code |
onStart(), onStop(), onError(), and onActivityExpired() |
| Stop inactive containers | setInactivityTimeout() |
sleepAfter and onActivityExpired() |
| Schedule callbacks | ctx.storage.setAlarm() (Durable Object API) |
schedule() |
For new applications, use the Durable Object Container API to combine direct container control with Durable Object storage and coordination. It also supports latency-sensitive workloads and applications that need a smaller storage footprint.
If your application uses the Container class, refer to Migrate to the Durable Object Container API.