Deploy full Docker containers to Cloudflare's edge network using Firecracker microVMs via Cloudflare Containers (Public Beta). Trigger: deploy container to cloudflare, cloudflare containers, wrangler containers, deploy docker to cloudflare edge, cloudflare container runtime
Status: Public Beta since June 2025. This skill will be updated when Cloudflare Containers reaches GA.
Available to all Workers Paid plan users ($5/month). Not yet generally available — global autoscaling and latency-aware routing are pending. Monitor the Cloudflare changelog for GA announcement.
Deploy and manage full Linux containers on Cloudflare's edge network. Unlike Workers (V8 isolates), Containers run arbitrary Docker images in Firecracker microVMs — any language, stateful filesystem, long-lived processes.
| Aspect | Workers | Containers |
|---|
| Runtime | V8 isolates (JS/TS/WASM) | Full Linux containers (any language) |
| Startup | Sub-millisecond | 2-3 seconds |
| Duration | Short-lived | Long-lived, persistent |
| State | Stateless (use bindings) | Stateful filesystem, in-memory |
| Isolation | V8 sandbox | Firecracker microVM + KVM |
| Languages | JavaScript, TypeScript, WASM | Any (Go, Python, Rust, Java, etc.) |
| Cost model | Per-request + active CPU | Per-second (vCPU + memory + disk) |
Containers are declared in wrangler.toml or wrangler.jsonc alongside Workers. A Worker acts as the entry point, routing requests to container instances. Containers are modeled as Durable Object classes.
wrangler CLI installed and authenticated:
npm install -g wrangler
wrangler login
Dockerfile in the projectwrangler.jsonc — define containers alongside the Worker:
{
"name": "my-container-app",
"main": "src/index.js",
"compatibility_date": "2025-06-01",
"containers": [
{
"class_name": "MyContainer",
"image": "./Dockerfile",
"instance_type": "standard-1",
"max_instances": 10,
"sleep_after": "5m"
}
],
"durable_objects": {
"bindings": [
{
"name": "MY_CONTAINER",
"class_name": "MyContainer"
}
]
}
}
Scale-to-zero with sleep_after: the container instance hibernates after the configured idle duration. Billing stops during sleep. Startup latency on wake is 2-3 seconds.
| Type | vCPU | Memory | Use Case |
|---|---|---|---|
| lite | Shared | 256 MiB | Lightweight tasks, sidecar processes |
| basic | Shared | 1 GiB | Small apps, scripts |
| standard-1 | 1 | 4 GiB | General purpose (recommended default) |
| standard-2 | 2 | 8 GiB | Compute-heavy workloads |
| standard-4 | 8 | 32 GiB | Heavy workloads, ML inference |
| custom | Configurable | Configurable | Specialized requirements |
Start with standard-1 for general workloads. Use lite or basic for tasks that do not need dedicated CPU.
The Worker routes requests to the container via Durable Objects:
// src/index.js
export { MyContainer } from './container';
export default {
async fetch(request, env) {
const id = env.MY_CONTAINER.idFromName('instance-1');
const stub = env.MY_CONTAINER.get(id);
return stub.fetch(request);
}
};
// src/container.js
import { Container } from 'cloudflare:containers';
export class MyContainer extends Container {
defaultPort = 8080;
sleepAfter = '5m';
override async onStart() {
console.log('Container started');
}
}
# Build and deploy (builds Docker image, uploads to CF, deploys Worker)
wrangler deploy
# Local development with container simulation
wrangler dev
# Stream logs from running containers
wrangler tail
# Check deployment status
wrangler deployments list
# List container instances
wrangler containers list
# View instance details
wrangler containers describe <instance-id>
# Force restart an instance
wrangler containers restart <instance-id>
# List versions
wrangler versions list
# Roll back to previous version
wrangler rollback
| Resource | Free Included | Overage |
|---|---|---|
| vCPU | 375 minutes/month | $0.00002/vCPU-second |
| Memory | 25 GB-hours/month | Usage-based |
| Disk | 200 GB-hours/month | Usage-based |
| Billing granularity | 10ms increments | Active CPU (not provisioned) |
Billing is for active CPU time only (since November 2025), not provisioned time. Scale-to-zero means idle containers do not incur ongoing cost.
Containers run as full Linux environments. Follow standard Docker best practices:
# Multi-stage build for smaller image
FROM golang:1.23-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/server
FROM alpine:3.20
RUN adduser -D appuser
USER appuser
COPY --from=builder /app /app
EXPOSE 8080
CMD ["/app"]
Keep images small — Cloudflare pulls them from the registry on deploy. Smaller images deploy faster.
These limitations apply during Public Beta and may be resolved at GA:
Use Containers when:
Use Workers when:
This skill will be updated when Cloudflare Containers reaches GA.