chore: import upstream snapshot with attribution
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:30:11 +08:00
commit 70bf21e064
5213 changed files with 731895 additions and 0 deletions
@@ -0,0 +1,20 @@
FROM node:22-alpine
WORKDIR /usr/src/app
RUN echo '{"name": "simple-node-app-a", "version": "1.0.0"}' > package.json
RUN npm install
RUN sleep 1
RUN echo 'const { createServer } = require("http");\
\
const server = createServer(function (req, res) {\
res.writeHead(200, { "Content-Type": "text/plain" });\
res.write("Hello from Container A");\
res.end();\
});\
\
server.listen(8080);\
' > app.js
EXPOSE 8080
@@ -0,0 +1,20 @@
FROM node:22-alpine
WORKDIR /usr/src/app
RUN echo '{"name": "simple-node-app-b", "version": "1.0.0"}' > package.json
RUN npm install
RUN sleep 1
RUN echo 'const { createServer } = require("http");\
\
const server = createServer(function (req, res) {\
res.writeHead(200, { "Content-Type": "text/plain" });\
res.write("Hello from Container B");\
res.end();\
});\
\
server.listen(8080);\
' > app.js
EXPOSE 8080
@@ -0,0 +1,49 @@
import { DurableObject } from "cloudflare:workers";
class FixtureTestContainerBase extends DurableObject<Env> {
container: globalThis.Container;
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.container = ctx.container;
}
async fetch(req: Request) {
if (!this.container.running) {
this.container.start({
entrypoint: ["node", "app.js"],
enableInternet: false,
});
// On the first request we simply start the container and return,
// on the following requests the container can actually be accessed.
// Note that we do this this way because container.start is not awaitable
// meaning that we can't simply wait here for the container to be ready
return new Response("Container started");
}
return this.container
.getTcpPort(8080)
.fetch("http://foo/bar/baz", { method: "POST", body: "hello" });
}
}
export class FixtureTestContainerA extends FixtureTestContainerBase {}
export class FixtureTestContainerB extends FixtureTestContainerBase {}
export default {
async fetch(request, env): Promise<Response> {
const getContainerText = async (
container: "CONTAINER_A" | "CONTAINER_B"
) => {
const id = env[container].idFromName("container");
const stub = env[container].get(id);
return await (await stub.fetch(request)).text();
};
const containerAText = await getContainerText("CONTAINER_A");
const containerBText = await getContainerText("CONTAINER_B");
return new Response(
`Response from A: "${containerAText}"` +
" " +
`Response from B: "${containerBText}"`
);
},
} satisfies ExportedHandler<Env>;
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020"],
"types": ["@cloudflare/workers-types"],
"moduleResolution": "node",
"noEmit": true,
"skipLibCheck": true
},
"include": ["**/*.ts"]
}
@@ -0,0 +1,14 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types ./multi-containers-app/src/worker-configuration.d.ts -c ./multi-containers-app/wrangler.jsonc --no-include-runtime` (hash: bbb41fc3f9d6ad4abf178ab91cb66515)
interface __BaseEnv_Env {
CONTAINER_A: DurableObjectNamespace<import("./index").FixtureTestContainerA>;
CONTAINER_B: DurableObjectNamespace<import("./index").FixtureTestContainerB>;
}
declare namespace Cloudflare {
interface GlobalProps {
mainModule: typeof import("./index");
durableNamespaces: "FixtureTestContainerA" | "FixtureTestContainerB";
}
interface Env extends __BaseEnv_Env {}
}
interface Env extends __BaseEnv_Env {}
@@ -0,0 +1,41 @@
{
"name": "multi-containers-app",
"main": "src/index.ts",
"compatibility_date": "2025-04-03",
"containers": [
{
"image": "./DockerfileA",
"class_name": "FixtureTestContainerA",
"name": "containerA",
"max_instances": 2,
},
{
"image": "./DockerfileB",
"class_name": "FixtureTestContainerB",
"name": "containerB",
"max_instances": 2,
},
],
"durable_objects": {
"bindings": [
{
"class_name": "FixtureTestContainerA",
"name": "CONTAINER_A",
},
{
"class_name": "FixtureTestContainerB",
"name": "CONTAINER_B",
},
],
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["FixtureTestContainerA"],
},
{
"tag": "v1",
"new_sqlite_classes": ["FixtureTestContainerB"],
},
],
}