Container class·续
};
Refer to the [env vars and secrets example](https://developers.cloudflare.com/containers/examples/env-vars-and-secrets/) for a full example.
### `start`
Start the container without waiting for all ports to become ready.
```ts
start(startOptions?: ContainerStartConfigOptions, waitOptions?: WaitOptions): Promise<void>
Parameters:
startOptions- Per-instance startup overrides.startOptions.envVars- Per-instance environment variables.startOptions.entrypoint- Entrypoint override for this start only.startOptions.enableInternet- Whether outbound internet access is allowed for this start.waitOptions.portToCheck- Port to probe while starting. If omitted, the class usesdefaultPort, the firstrequiredPortsentry, or a fallback port.waitOptions.signal- Abort signal to cancel startup.waitOptions.retries- Maximum number of start attempts before the method throws.waitOptions.waitInterval- Polling interval in milliseconds between retries.
Returns: Promise<void>. Resolves after the start attempt succeeds and onStart() has run.
Use this when the container does not expose ports, such as a batch job or a cron task, or when you want to manage readiness yourself with waitForPort(). If you need to wait for all ports to be ready, use startAndWaitForPorts() instead.
import { getContainer } from "@cloudflare/containers";
export default {
async scheduled(_event, env) {
const container = getContainer(env.JOB_CONTAINER, "nightly-report");
await container.start({
entrypoint: ["node", "scripts/nightly-report.js"],
envVars: {
REPORT_DATE: new Date().toISOString(),
},
enableInternet: false,
});
},
};
import { getContainer } from "@cloudflare/containers";
export default {
async scheduled(_event, env) {
const container = getContainer(env.JOB_CONTAINER, "nightly-report");
await container.start({
entrypoint: ["node", "scripts/nightly-report.js"],
envVars: {
REPORT_DATE: new Date().toISOString(),
},
enableInternet: false,
});
},
};
Refer to the cron example for a full example.
waitForPort
Poll a single port until it accepts connections.
waitForPort(waitOptions: WaitOptions): Promise<number>
Parameters:
waitOptions.portToCheck- Port number to check.waitOptions.signal- Abort signal to cancel waiting.waitOptions.retries- Maximum number of retries before the method throws.waitOptions.waitInterval- Polling interval in milliseconds.
Returns: Promise<number>. The numeric return value is mainly useful when you are coordinating custom readiness logic across multiple waits.
Throws if the port does not become available within the retry limit. Use this after start() when you need to check multiple ports independently or in a specific sequence.
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
async warmInspector() {
await this.start();
const retryCount = await this.waitForPort({
portToCheck: 9222,
retries: 20,
waitInterval: 500,
});
console.log("Inspector port became ready:", retryCount);
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
async warmInspector() {
await this.start();
const retryCount = await this.waitForPort({
portToCheck: 9222,
retries: 20,
waitInterval: 500,
});
console.log("Inspector port became ready:", retryCount);
}
}
stop
Send a signal to the container process.
stop(signal?: 'SIGTERM' | 'SIGINT' | 'SIGKILL' | number): Promise<void>
Parameters:
signal- Signal to send. Defaults to'SIGTERM'.
Returns: Promise<void>. Resolves after the signal is sent and pending stop handling has completed.
Defaults to SIGTERM, which gives the process a chance to shut down gracefully. Triggers onStop().
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
async fetch(request) {
if (new URL(request.url).pathname === "/admin/stop") {
await this.stop();
return new Response("Container is stopping");
}
return this.containerFetch(request);
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
override async fetch(request: Request): Promise<Response> {
if (new URL(request.url).pathname === "/admin/stop") {
await this.stop();
return new Response("Container is stopping");
}
return this.containerFetch(request);
}
}
destroy
Immediately kill the container process.
destroy(): Promise<void>
Returns: Promise<void>. Resolves after the runtime has destroyed the container.
This sends SIGKILL. Use it when you need the container gone immediately and cannot wait for a graceful shutdown. Triggers onStop().
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
async fetch(request) {
if (new URL(request.url).pathname === "/admin/destroy") {
await this.destroy();
return new Response("Container destroyed");
}
return this.containerFetch(request);
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
override async fetch(request: Request): Promise<Response> {
if (new URL(request.url).pathname === "/admin/destroy") {
await this.destroy();
return new Response("Container destroyed");
}
return this.containerFetch(request);
}
}
State and monitoring
getState
Read the current container state.
getState(): Promise<State>
Returns: Promise<State> with:
status- One of'running','healthy','stopping','stopped', or'stopped_with_code'.lastChange- Unix timestamp in milliseconds for the last state change.exitCode- Optional exit code whenstatusis'stopped_with_code'.
running means the container is starting and has not yet passed its health check. healthy means it is up and accepting requests.
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
async logState() {
const state = await this.getState();
if (state.status === "stopped_with_code") {
console.error("Container exited with code", state.exitCode);
return;
}
console.log("Container status:", state.status);
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
async logState() {
const state = await this.getState();
if (state.status === "stopped_with_code") {
console.error("Container exited with code", state.exitCode);
return;
}
console.log("Container status:", state.status);
}
}
renewActivityTimeout
Reset the sleepAfter timer.
renewActivityTimeout(): void
Returns: void.
Incoming requests reset the timer automatically. Call this manually from background work, such as a scheduled task or a long-running operation, that should count as activity and prevent the container from sleeping.
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
async processJobs(jobIds) {
for (const jobId of jobIds) {
this.renewActivityTimeout();
await this.containerFetch(`http://localhost/jobs/${jobId}`, {
method: "POST",
});
}
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
async processJobs(jobIds: string[]) {
for (const jobId of jobIds) {
this.renewActivityTimeout();
await this.containerFetch(`http://localhost/jobs/${jobId}`, {
method: "POST",
});
}
}
}
Scheduling
schedule
Schedule a method on the class to run later.
schedule<T>(when: Date | number, callback: string, payload?: T): Promise<Schedule<T>>
Parameters:
when- Either aDatefor a specific time or a number of seconds to delay.callback- Name of the class method to call.payload- Optional data passed to the callback method.
Returns: Promise<Schedule<T>> with:
taskId- Unique schedule ID.callback- Method name that will be called.payload- Payload that will be passed to the callback.type-'scheduled'for an absolute time or'delayed'for a relative delay.time- Unix timestamp in seconds when the task will run.delayInSeconds- Delay in seconds whentypeis'delayed'.
Do not override alarm() ↗︎ directly. The Container class uses the alarm handler to manage the container lifecycle, so use schedule() instead.
The following example schedules a recurring health report starting at container startup:
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
async onStart() {
await this.schedule(60, "healthReport");
}
async healthReport() {
const state = await this.getState();
console.log("Container status:", state.status);
await this.schedule(60, "healthReport");
}
}
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
override async onStart() {
await this.schedule(60, "healthReport");
}
async healthReport() {
const state = await this.getState();
console.log("Container status:", state.status);
await this.schedule(60, "healthReport");
}
}
Outbound interception
Outbound interception lets you intercept, mock, or block HTTP requests that the container makes to external hosts. This is useful for sandboxing, testing, or proxying outbound traffic through Worker code.
import {
Container,
ContainerProxy,
getContainer,
} from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
enableInternet = true;
static outboundByHost = {
"blocked.example.com": () => {
return new Response("Blocked", { status: 403 });
},
};
static outbound = async (request, _env, ctx) => {
console.log(`[${ctx.containerId}] outbound:`, request.url);
return fetch(request);
};
}
export { ContainerProxy };
export default {
async fetch(request, env) {
return getContainer(env.MY_CONTAINER).fetch(request);
},
};
import {
Container,
ContainerProxy,
getContainer,
} from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
enableInternet = true;
static outboundByHost = {
"blocked.example.com": () => {
return new Response("Blocked", { status: 403 });
},
};
static outbound = async (request, _env, ctx) => {
console.log(`[${ctx.containerId}] outbound:`, request.url);
return fetch(request);
};
}
export { ContainerProxy };
export default {
async fetch(request: Request, env) {
return getContainer(env.MY_CONTAINER).fetch(request);
},
};
For more information, refer to Handle outbound traffic.
Utility functions
These functions are exported alongside the Container class from @cloudflare/containers.
getContainer
Get a stub for a named container instance.
getContainer<T>(binding: DurableObjectNamespace<T>, name?: string): DurableObjectStub<T>
Parameters:
binding- Durable Object namespace binding for your container class.name- Stable instance name. Defaults tocf-singleton-container.
Returns: DurableObjectStub<T> for the named container instance.
Use this when you want one container per logical entity, such as a user session, a document, or a game room, identified by a stable name.
import { getContainer } from "@cloudflare/containers";
export default {
async fetch(request, env) {
const { sessionId } = await request.json();
return getContainer(env.MY_CONTAINER, sessionId).fetch(request);
},
};
import { getContainer } from "@cloudflare/containers";
export default {
async fetch(request: Request, env) {
const { sessionId } = await request.json();
return getContainer(env.MY_CONTAINER, sessionId).fetch(request);
},
};
getRandom
Get a stub for a randomly selected container instance.
getRandom<T>(binding: DurableObjectNamespace<T>, instances?: number): Promise<DurableObjectStub<T>>
Parameters:
binding- Durable Object namespace binding for your container class.instances- Total number of instances to choose from. Defaults to3.
Returns: Promise<DurableObjectStub<T>> for the randomly selected instance.
Use this for stateless workloads where any container can handle any request and you want to spread load across multiple instances.
import { getRandom } from "@cloudflare/containers";
export default {
async fetch(request, env) {
const container = await getRandom(env.WORKER_POOL, 5);
return container.fetch(request);
},
};
import { getRandom } from "@cloudflare/containers";
export default {
async fetch(request: Request, env) {
const container = await getRandom(env.WORKER_POOL, 5);
return container.fetch(request);
},
};
Refer to the stateless instances example for a full example.
switchPort
Target a different container port while still using fetch().
switchPort(request: Request, port: number): Request
Parameters:
request- Request to copy.port- Port to encode into the request headers.
Returns: Request copy with the target port set.
Use this when you need to target a specific port and also need WebSocket support. If you do not need WebSockets, pass the port directly to containerFetch() instead.
import { getContainer, switchPort } from "@cloudflare/containers";
export default {
async fetch(request, env) {
const container = getContainer(env.MY_CONTAINER);
return container.fetch(switchPort(request, 9090));
},
};
import { getContainer, switchPort } from "@cloudflare/containers";
export default {
async fetch(request: Request, env) {
const container = getContainer(env.MY_CONTAINER);
return container.fetch(switchPort(request, 9090));
},
};
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/containers/api/container-class/#page","headline":"Container class","description":"API reference for the Container class and its built-in lifecycle helpers.","url":"https://developers.cloudflare.com/containers/api/container-class/","inLanguage":"en","image":"https://developers.cloudflare.com/containers/api/container-class/og.png?v=26c6ffaa28be5042","dateModified":"2026-09-30","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Access and manage containers associated with a Durable Object, including start, stop, and interaction methods. title: Durable Object Container API image: https://developers.cloudflare.com/containers/api/durable-object-container/og.png?v=f13dbe1f95442c69
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/containers/llms.txt
Use this file to discover all available pages before exploring further.
Docs