This site is not affiliated with or endorsed by Cloudflare, Inc. It simply showcases experiments built using Cloudflare services.
Cloudflare Experiments
Compute & Isolation

Container Echo

Echo a message via Cloudflare Containers backed by a Durable Object

Echo a message through Cloudflare Containers. A Durable Object subclass (EchoContainer) extends @cloudflare/containers's Container and proxies requests to a Node HTTP server running in the container image.

API Reference

POST /echo

Send text/plain or JSON ({ "message": "..." } or { "echo": "..." }).

Body must be non-empty and at most 10,000 characters.

Example Request

curl -X POST "https://your-worker.workers.dev/echo" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

Success Response

{
  "echo": "hello",
  "port": 8080
}

Error Codes

  • 400 - Invalid or empty body (INVALID_BODY)
  • 502 - Container or proxy failure (ECHO_ERROR)

Use Cases

  • Learn Containers + Durable Object lifecycle with a minimal API
  • Prototype Worker-to-container request forwarding
  • Validate Dockerfile-backed images on Cloudflare
  • Compare Containers vs pure Workers for Node-style servers

Limitations

  • Docker must be available for wrangler dev / deploy image builds
  • Message body capped at 10,000 characters
  • Demo exposes a single echo path; not a general proxy
  • Container instances are limited (max_instances: 2 in wrangler)

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/container-echo.

DependenciesNoneBindingsDurable Objects, ContainersPlatformFetch API, Durable Objects
import type { Env } from "../types/env";import type { EchoResult } from "../types/echo";const INSTANCE_NAME = "default";export function getEchoStub(env: Env): DurableObjectStub {  if (typeof env.ECHO.getByName === "function") {    return env.ECHO.getByName(INSTANCE_NAME);  }  const id = env.ECHO.idFromName(INSTANCE_NAME);  return env.ECHO.get(id);}export async function echoMessage(env: Env, message: string): Promise<EchoResult> {  const stub = getEchoStub(env);  const response = await stub.fetch("https://echo/echo", {    method: "POST",    headers: { "Content-Type": "text/plain" },    body: message,  });  if (!response.ok) {    throw new Error(`Container echo failed with status ${response.status}`);  }  return (await response.json()) as EchoResult;}export function validateMessage(input: string | undefined | null): string | null {  if (typeof input !== "string") return null;  if (input.length === 0 || input.length > 10_000) return null;  return input;}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Deploy

Wrangler builds ./Dockerfile, registers the EchoContainer Durable Object, and binds it as ECHO.

Test your deployment

curl -X POST "https://your-worker.workers.dev/echo" \
  -H "Content-Type: text/plain" \
  -d "hello"

Local Development

Docker must be running for container image builds.

cd apps/experiments/container-echo
npm install
npm run dev
curl -X POST "http://localhost:8787/echo" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

Unit tests mock the Durable Object binding so Docker is not required for npm run test.

Configuration

wrangler.json declares:

  • Container EchoContainer from ./Dockerfile (port 8080)
  • Durable Object binding ECHO → EchoContainer
  • Migration v1 with new_sqlite_classes: ["EchoContainer"]

Cloudflare Features Used

On this page