On one laptop, with one VPN client connected, Linux containers keep talking to each other and Windows containers stop. The image is not the variable; the path the packets take into the host is. Windows containers on the default network borrow the host's route table and translation, so a policy that changes host routing changes them too. Confirm that with a route lookup before reinstalling anything.

Where a Windows container's packets enter the host

A container on the default nat network gets an address from a Host Networking Service prefix, usually somewhere inside 172.16.0.0/12, and reaches the host through a virtual adapter. The host owns the route for that prefix and translates traffic toward whichever adapter is current. There is no separate virtual machine in the middle of that path.

That design is what makes the failure mechanical. When the container sends a packet, the host performs a route lookup for the container prefix. Whatever route wins is where the packet goes, and the container has no opinion about it.

What the VPN client changes about that path

A corporate client often installs a broad set of routes and a filter that denies access to the local subnet while the tunnel is up. The intent is defensive: a compromised local network should not reach a protected machine. The side effect is that the host's route to the container prefix is no longer the local NAT network.

Instead, the lookup matches the tunnel and the packet is handed to the gateway, which has never heard of that container address. Ping fails, the application times out, and the container looks broken while the VPN icon glows. Check the host's table while connected and the competing route is visible.

Container modeOutbound pathTypical result behind the VPN
Windows, default natHost routes and translates container trafficContainer prefix follows the tunnel and fails
Windows, transparentContainer sits on the physical linkDepends on the local subnet being allowed
Linux engine on Docker DesktopVM egress proxied by a host processOften keeps working

Why Linux containers behave differently

The Linux engine runs containers inside a lightweight virtual machine, and outbound connections from that machine are opened by a host-side proxy on the container's behalf. The host initiates the socket, so the VPN's rule about the container prefix does not apply to it in the same way, and the workload keeps reaching the network.

That difference also explains why Linux recipes do not port. A Linux container that needs its own tunnel is given a TUN device plus the NET_ADMIN capability. Windows containers expose no interface as a device, so that pattern has no equivalent on that side.

Prove the route, then choose a design

Collect evidence from the host, not from the container, because the host performs the lookup:

docker network inspect nat --format "{{range .IPAM.Config}}{{.Subnet}}{{end}}"
route print -4
Get-NetRoute -AddressFamily IPv4 | Where-Object DestinationPrefix -like "172.16.*"

Run the route output once before the VPN connects and once after. If the container prefix points at the tunnel adapter in the second output, the diagnosis is complete and restarting containers will not help.

The first option is a policy decision: ask the network owner whether local LAN access can be allowed for this device. Several corporate clients expose that as a setting, but it weakens a deliberate boundary. Ask for it as a documented exception with an owner and a review date. A per-device toggle that nobody revisits is how a defensive policy quietly disappears.

Where the policy must stand, move the workload instead of fighting the route. A transparent network with an explicit subnet and gateway puts containers on the local link, a Linux workload runs behind the VM proxy, and a separate virtual machine with its own client keeps its own policy. Pick one deliberately and test it from inside the container, because that is where the user's request originates.

Tënë sô zo