Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/funny-mails-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"wrangler": minor
"miniflare": minor
"@cloudflare/vite-plugin": minor
---

Enable container egress interception in local dev without the `experimental` compatibility flag

Container local development now always prepares the egress interceptor sidecar image needed for `interceptOutboundHttp()`. This makes container-to-Worker interception available by default in Wrangler, Miniflare, and the Cloudflare Vite plugin.
12 changes: 5 additions & 7 deletions packages/containers-shared/src/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import type {
WranglerLogger,
} from "./types";

const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE =
"cloudflare/proxy-everything:4dc6c7f@sha256:9621ef445ef120409e5d95bbd845ab2fa0f613636b59a01d998f5704f4096ae2";
export const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE =
"cloudflare/proxy-everything:3f5e832@sha256:816255f5b6ebdc2cdcddb578d803121e7ee9cfe178442da07725d75a66cdcf37";

export function getEgressInterceptorImage(): string {
return (
Expand Down Expand Up @@ -114,7 +114,6 @@ export async function prepareContainerImagesForDev(args: {
}) => void;
logger: WranglerLogger | ViteLogger;
isVite: boolean;
compatibilityFlags?: string[];
}): Promise<void> {
const {
dockerPath,
Expand Down Expand Up @@ -171,10 +170,9 @@ export async function prepareContainerImagesForDev(args: {
}
}

// Pull the egress interceptor image if experimental flag is enabled.
// This image is used to intercept outbound HTTP from containers and
// route it back to workerd (e.g. for interceptOutboundHttp).
if (!aborted && args.compatibilityFlags?.includes("experimental")) {
// Pull the egress interceptor image used to intercept outbound HTTP from
// containers and route it back to workerd (e.g. for interceptOutboundHttp).
if (!aborted) {
await pullEgressInterceptorImage(dockerPath);
}
}
Expand Down
17 changes: 4 additions & 13 deletions packages/miniflare/src/plugins/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import path from "node:path";
import { Readable } from "node:stream";
import tls from "node:tls";
import { TextEncoder } from "node:util";
import { DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE } from "@cloudflare/containers-shared";
import { bold } from "kleur/colors";
import { MockAgent } from "undici";
import SCRIPT_ENTRY from "worker:core/entry";
Expand Down Expand Up @@ -908,10 +909,7 @@ export const CORE_PLUGIN: Plugin<
);
}
),
containerEngine: getContainerEngine(
options.containerEngine,
options.compatibilityFlags
),
containerEngine: getContainerEngine(options.containerEngine),
},
});
}
Expand Down Expand Up @@ -1214,9 +1212,6 @@ function getWorkerScript(
}
}

const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE =
"cloudflare/proxy-everything:4dc6c7f@sha256:9621ef445ef120409e5d95bbd845ab2fa0f613636b59a01d998f5704f4096ae2";

/**
* Returns the default containerEgressInterceptorImage. It's used for
* container network interception for local dev.
Expand All @@ -1234,8 +1229,7 @@ function getContainerEgressInterceptorImage(): string {
* @returns The container engine, defaulting to the default docker socket located on linux/macOS at `unix:///var/run/docker.sock`
*/
function getContainerEngine(
engineOrSocketPath: Worker_ContainerEngine | string | undefined,
compatibilityFlags?: string[]
engineOrSocketPath: Worker_ContainerEngine | string | undefined
): Worker_ContainerEngine {
if (!engineOrSocketPath) {
// TODO: workerd does not support win named pipes
Expand All @@ -1245,13 +1239,10 @@ function getContainerEngine(
: "unix:///var/run/docker.sock";
}

// TODO: Once the feature becomes GA, we should remove the experimental requirement.
// Egress interceptor is to support direct connectivity between the Container and Workers,
// it spawns a container in the same network namespace as the local dev container and
// intercepts traffic to redirect to Workerd.
const egressImage = compatibilityFlags?.includes("experimental")
? getContainerEgressInterceptorImage()
: undefined;
const egressImage = getContainerEgressInterceptorImage();

if (typeof engineOrSocketPath === "string") {
return {
Expand Down
3 changes: 0 additions & 3 deletions packages/vite-plugin-cloudflare/src/plugins/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,6 @@ export const devPlugin = createPlugin("dev", (ctx) => {
onContainerImagePreparationEnd: () => {},
logger: viteDevServer.config.logger,
isVite: true,
compatibilityFlags: ctx.allWorkerConfigs.flatMap(
(c) => c.compatibility_flags
),
});

containerImageTags = new Set(containerTagToOptionsMap.keys());
Expand Down
3 changes: 0 additions & 3 deletions packages/vite-plugin-cloudflare/src/plugins/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ export const previewPlugin = createPlugin("preview", (ctx) => {
onContainerImagePreparationEnd: () => {},
logger: vitePreviewServer.config.logger,
isVite: true,
compatibilityFlags: ctx.allWorkerConfigs.flatMap(
(c) => c.compatibility_flags
),
});

const containerImageTags = new Set(containerTagToOptionsMap.keys());
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/e2e/containers.dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ for (const source of imageSource) {
name: `${workerName}`,
main: "src/index.ts",
compatibility_date: "2025-04-03",
compatibility_flags: ["experimental", "enable_ctx_exports"],
compatibility_flags: ["enable_ctx_exports"],
containers: [
{
image: "./Dockerfile",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ export class LocalRuntimeController extends RuntimeController {
},
logger: logger,
isVite: false,
compatibilityFlags: data.config.compatibilityFlags,
});
if (this.containerBeingBuilt) {
this.containerBeingBuilt.abortRequested = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ export class MultiworkerRuntimeController extends LocalRuntimeController {
},
logger: logger,
isVite: false,
compatibilityFlags: data.config.compatibilityFlags,
});
if (this.containerBeingBuilt) {
this.containerBeingBuilt.abortRequested = false;
Expand Down
Loading