To get logs in the Dashboard, including live tailing of logs, toggle observability to true
in your Worker's wrangler config:
{
"observability": {
"enabled": true
}
}[observability]
enabled = trueLogs are subject to the same limits as Workers Logs and are retained for seven days.
Beginning December 1, 2026, Container logs use Cloudflare Observability pricing.
You can export container logs via Logpush to your preferred destination.
When initially deploying a Container, Cloudflare will select various locations across our network to deploy instances to. These locations will span multiple regions.
When a Container instance is requested with this.ctx.container.start, the nearest free
container instance will be selected from the pre-initialized locations. This will
likely be in the same region as the external request, but may not be. Once the container
instance is running, any future requests will be routed to the initial location.
An Example:
- A user deploys a Container. Cloudflare automatically readies instances across its Network.
- A request is made from a client in Bariloche, Argentina. It reaches the Worker in Cloudflare's location in Neuquen, Argentina.
- This Worker request calls
MY_CONTAINER.get("session-1337")which brings up a Durable Object, which then callsthis.ctx.container.start. - This requests the nearest free Container instance.
- Cloudflare recognizes that an instance is free in Buenos Aires, Argentina, and starts it there.
- A different user needs to route to the same container. This user's request reaches the Worker running in Cloudflare's location in San Diego.
- The Worker again calls
MY_CONTAINER.get("session-1337"). - If the initial container instance is still running, the request is routed to the location in Buenos Aires. If the initial container has gone to sleep, Cloudflare will once again try to find the nearest "free" instance of the Container, likely one in North America, and start an instance there.
On wrangler deploy, the Worker goes live first. Container instances update with a gradual rollout by default. Refer to Rollouts for steps, grace periods, and modes. Refer to Deploy Containers to run a deploy.
On the production branch, Workers Builds should run wrangler deploy so images and container instances can update. Non-production Workers Builds defaults to wrangler versions upload, which does not update images. Containers Workers implement Durable Objects, so preview URLs are not generated for them. Refer to Deploy Containers.
Containers scale by creating or addressing specific instances. For stateless routing across a
fixed number of interchangeable instances, use the getRandom helper.
Refer to scaling and routing for details.
Not today, though Cloudflare plans to add built-in autoscaling in a future release.
Until then, use getRandom for simple stateless routing and specific instance IDs when you need
explicit control over container lifecycle.
A cold start is when a container instance is started from a completely stopped state.
If you call env.MY_CONTAINER.get(id) with a completely novel ID and launch
this instance for the first time, it will result in a cold start.
This will start the container image from its entrypoint for the first time. Depending on what this entrypoint does, it will take a variable amount of time to start.
Container cold starts can often be in the 1-3 second range, but this is dependent on image size and code execution time, among other factors.
Refer to image management.
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, Container applications that 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.
You can also use FUSE to persist disk to R2 or other object storage backends. Though you should not expect native SSD-like performance while using FUSE.
If you run out of memory, your instance will throw an Out of Memory (OOM) error and will be restarted.
Containers do not use swap memory.
Cloudflare does not stop a container instance after a fixed maximum runtime. With the Durable Object Container API, call setInactivityTimeout() to stop an inactive container. The Container class sets sleepAfter to 10 minutes by default. Its onActivityExpired() implementation signals the container to stop after that period without activity. You can change the duration or override the hook.
Another platform event can stop an active container. For example, a host server restart happens on an irregular cadence. Cloudflare does not guarantee that any container instance will run for a set period.
When the platform is about to stop a container instance (including before a host moves work off a server), it:
- Sends
SIGTERMto the main process in the container. - Waits up to 15 minutes for that process to exit.
- Sends
SIGKILLif the process is still running.
Handle SIGTERM in your image if you need cleanup before exit. After a host stop, a new container instance may start on a different server when traffic needs it again.
Image updates during a deploy use the same stop sequence. Refer to Rollouts.
You can use Worker Secrets or the Secrets Store to define secrets for your Workers.
For implementation details, refer to Environment variables and secrets.
Yes. Use the docker:dind image, and start the Docker daemon with iptables and IP forwarding turned off:
FROM docker:dind
# Start dockerd with iptables and IP forwarding turned off, then run your app
ENTRYPOINT ["sh", "-c", "dockerd-entrypoint.sh dockerd --iptables=false --ip6tables=false --ip-forward=false & exec /path/to/your-app"]This Dockerfile works with both scheduling policies. Containers that use the durable_object policy cannot turn on IP forwarding. In those containers, the Docker daemon exits on startup unless you pass --ip-forward=false.
Run the Docker daemon as root. Rootless Docker does not start in Containers.
If your application needs to wait for dockerd to become ready before using Docker, use an entrypoint script instead of the inline command above:
#!/bin/sh
set -eu
# Wait for dockerd to be ready
until docker version >/dev/null 2>&1; do
sleep 0.2
done
exec /path/to/your-appFor a complete working example, refer to the Docker-in-Docker Containers example ↗︎. The example uses the default scheduling policy. To run it with scheduling_policy: "durable_object", add --ip-forward=false to its dockerd flags.
Refer to Handle outbound traffic for how to control outbound traffic and internet access.