Two containers communicating over configurable ports
The Worker is the routing layer. It receives requests and forwards them to containers on any port.
name = "my-app" main = "src/index.ts" # Define your containers [[containers]] class_name = "ContainerA" image = "./containers/a/Dockerfile" instances = 3 [[containers]] class_name = "ContainerB" image = "./containers/b/Dockerfile" instances = 3 # Containers are backed by Durable Objects [[durable_objects.bindings]] class_name = "ContainerA" name = "CONTAINER_A" [[durable_objects.bindings]] class_name = "ContainerB" name = "CONTAINER_B"
import { Container, getContainer } from "@cloudflare/containers"; // Container A - set the port it listens on export class ContainerA extends Container { override port = 8080; // <-- change this! } // Container B - different port export class ContainerB extends Container { override port = 3000; // <-- change this! } export default { async fetch(req, env) { // Get container instances const a = getContainer(env.CONTAINER_A, "a"); const b = getContainer(env.CONTAINER_B, "b"); // Forward request from A -> B const data = await a.fetch("/get-payload"); const result = await b.fetch("/receive", { method: "POST", body: data.body, }); return result; }, };
FROM golang:1.22-alpine WORKDIR /app COPY . . RUN go build -o server . # EXPOSE only needed for local dev # In production, all ports are auto-accessible EXPOSE 8080 CMD ["./server"]
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/get-payload", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, `{"event": "ping", "from": "container-a"}`) }) // Listen on the port the Worker expects fmt.Println("Container A listening on :8080") http.ListenAndServe(":8080", nil) }
-p 8080:3000 port mapping like Docker.
The Worker IS the routing layer. It calls container.fetch() which hits whatever port
you set in override port. In production, all container ports are automatically
accessible to the Worker - no EXPOSE needed. Your app just listens on a port, and the Worker knows where to find it.