cloudflare / cloudflare/workers-sdk
wrangler dev (containers): egress gateway bound to native-WSL docker0 is unreachable from Docker Desktop VM — all container egress resets on WSL2
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.5k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 186
Description
### Which Cloudflare product(s) does this pertain to?
Wrangler, Containers
### What versions are you using?
wrangler 4.123.0, miniflare 5.20260811.1-alpha, @cloudflare/sandbox 0.12.5, @cloudflare/containers 0.3.7
### What operating system and version are you using?
Windows 11 + WSL2 (Ubuntu 24.04), Docker Desktop 29.4.0 (WSL2 backend)
### Describe the Bug
**Observed behavior**
Running `wrangler dev --local` for a Worker with containers (`@cloudflare/sandbox`) on WSL2 while Docker Desktop is the active engine, ALL outbound traffic from the container fails:
- DNS resolves, raw TCP connects, but every payload-carrying connection is reset (`curl` exit 35 `Connection reset by peer` on the TLS ClientHello, plain HTTP on port 80 also dies).
- `pnpm install` inside the container fails; `cloudflared` quick tunnels cannot register.
**Root cause (diagnosed)**
- workerd binds the container egress gateway to `172.17.0.1:` — the docker0 bridge IP of the *native WSL dockerd* (`ss -tlnp` shows e.g. `172.17.0.1:37087 … users:(("workerd",…))`).
- The containers, however, run inside the Docker Desktop VM, whose bridge gateway `172.17.0.1` is a *different* interface. The `cloudflare/proxy-everything` sidecar falls back to dialing the host at `192.168.65.254:` (Docker Desktop's host gateway), which lands on the Windows host — where nothing forwards to WSL's `172.17.0.1`-bound listener.
- Sidecar log loops with: `error: connecting to origin: dialing gateway: dial tcp 192.168.65.254:37087: connect: connection refused`.
So the egress gateway address chosen by workerd (native-WSL bridge IP) is unreachable from the network namespace where Docker Desktop actually runs the containers.
**Expected behavior**
Container egress works under `wrangler dev --local` with Docker Desktop on WSL2 — e.g. by binding the egress gateway to loopback/wildcard so Docker Desktop's `host.docker.internal` path (VM → Windows host → WSL localhostForwarding) can reach it, or by detecting the Desktop engine and choosing a reachable address.
**Workaround that confirms the diagnosis**
A tiny TCP relay inside WSL listening on `127.0.0.1:` and eth0, forwarding to `172.17.0.1:`, fully restores egress (the sidecar reaches it via `192.168.65.254` → Windows localhost → WSL localhostForwarding): with the relay up, `pnpm install` succeeds inside the container and cloudflared quick tunnels register normally.
### Please provide a link to a minimal reproduction
Any `@cloudflare/sandbox` worker with `enableInternet = true` run via `wrangler dev --local` on WSL2 with Docker Desktop; then `exec` a `curl https://example.com` in the sandbox.
### Please provide any relevant error logs
```
# sidecar (docker logs -proxy)
error: connecting to origin: dialing gateway: dial tcp 192.168.65.254:37087: connect: connection refused
# inside the container
$ curl -v https://registry.npmjs.org/
* OpenSSL SSL_connect: Connection reset by peer in connection to registry.npmjs.org:443
# WSL host
$ ss -tlnp | grep 37087
LISTEN 0 4096 172.17.0.1:37087 0.0.0.0:* users:(("workerd",…))
```
Contributor guide
Research direction
Start by reproducing the issue with `wrangler dev --local` using an `@cloudflare/sandbox` Worker with `enableInternet = true`, then inspect the workerd egress-gateway address and the `cloudflare/proxy-everything` sidecar logs. Use the reported `ss -tlnp` listener and `192.168.65.254` connection-refused error to trace reachability under Docker Desktop; done means container `curl`, `pnpm install`, and cloudflared quick tunnels work without a relay.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, linux, typescript
- Domain
- cli, infrastructure, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100