Getting a Docker container inside Windows Subsystem for Linux (WSL) to accept traffic from other devices on your local area network (LAN) often feels like solving a puzzle. You run a container, test it on your Windows browser using localhost, and it works instantly. However, when a colleague or a secondary device on your network tries to reach that same service using your computer’s IP address, the request times out or gets rejected.
This barrier exists because WSL 2 operates as a virtualized Linux environment. Windows isolates the WSL 2 virtual machine behind a dedicated virtual network adapter. While Windows automatically routes localhost traffic into WSL 2 for your convenience, it does not automatically bridge incoming traffic from your physical Ethernet or Wi-Fi card directly into the container.
Resolving this issue requires matching your network routing to your specific environment. The exact steps depend on whether you are using Docker Desktop for Windows or running Docker Engine manually inside a bare Linux distribution. This guide provides the practical steps, network configurations, and firewall settings needed to make your containerized services accessible across your local network securely.
Why Docker Ports in WSL Are Not Always Accessible on Your Network
When you start a Docker container in WSL 2 and map a port, the container binds to a virtual network interface inside the Linux instance. Opening a web browser on Windows and navigating to localhost:3000 works because Windows handles loopback traffic internally. The operating system intercepts traffic sent to localhost and passes it directly to the WSL 2 virtual machine interface.
Outside devices cannot perform this loopback trick. When a smartphone, tablet, or another PC on your network sends a request to your Windows machine’s IP address (such as 192.168.1.50:3000), that packet lands on your physical network interface card. Because WSL 2 uses Network Address Translation (NAT) by default, your router and local network have no knowledge of the private internal network handling the Linux environment.
Your container runtime setup changes how traffic flows:
- Docker Desktop: Runs a background proxy service on Windows that listens on host ports and automatically forwards incoming packets through to the Linux container namespace.
- Standalone Docker Engine inside WSL 2: Binds ports strictly inside the Linux virtual environment. Windows does not automatically forward incoming external traffic hitting your physical card to the Linux kernel without explicit port proxy rules or mirrored networking.
Publish the Docker Container Port
Before any network bridging can happen, Docker must be instructed to map the container’s internal listening port to the host system interface. This is managed during container initialization.
To publish a port using the command-line interface, run your container with the -p flag:
Bash
docker run -d -p 3000:3000 –name web-app nginx
In this command structure, the value before the colon (3000) represents the host port, while the value after the colon (3000) represents the port inside the container.
If your setup uses Docker Compose, define the port bindings inside your docker-compose.yml file:
YAML
services:
web:
image: nginx
ports:
– “3000:3000”
To confirm that Docker has opened the port correctly, list your active containers:
Bash
docker ps
Check the PORTS column in the terminal output for an entry like 0.0.0.0:3000->3000/tcp, which confirms that Docker is listening on all network interfaces.
Note: Ensure the application running inside your container binds to 0.0.0.0 rather than 127.0.0.1. If a framework is configured to listen strictly to 127.0.0.1 inside the container, it will reject packets routed from outside the container network.
Choose the Right WSL Networking Method
Use the Default NAT Networking Mode
By default, WSL 2 creates an isolated virtual network operating under NAT. The Linux distribution gets a private virtual IP address while Windows acts as the gateway router.
To inspect your current WSL 2 virtual IP address, open your Linux terminal and execute:
Bash
hostname -I
While this IP address allows Windows to communicate directly with Linux, it has one major limitation: the WSL 2 IP address is dynamic. Every time WSL shuts down, restarts, or your host machine reboots, Windows generates a new virtual network adapter with a different IP address.
If you use Docker Desktop, NAT mode works without manual IP tracking because Docker Desktop manages host-level port bindings automatically. However, if you are running raw Docker Engine inside WSL 2, default NAT mode requires manual port forwarding on the Windows side every time your WSL IP updates.
Enable Mirrored Networking Mode
On updated builds of Windows 11, Microsoft introduced Mirrored Networking Mode for WSL 2. This feature mirrors your physical network interfaces directly into Linux. Ports opened in WSL 2 are automatically bound to your Windows host card, making your Linux containers natively accessible on your physical LAN without manual IP forwarding.
You can enable this setting manually by creating or editing the .wslconfig file in your Windows user profile folder (C:\Users\YourUsername.wslconfig):
Ini, TOML
[wsl2]
networkingMode=mirrored
To apply the configuration, shut down WSL completely from an elevated PowerShell or Command Prompt:
PowerShell
wsl –shutdown
Reopen your Linux distribution terminal. In mirrored mode, applications and Docker containers running inside WSL 2 attach directly to your main Windows IP address, eliminating the need to configure dynamic IP forwarding scripts.
Forward Ports From Windows Natively When Necessary
If you run Docker Engine directly inside WSL 2 without Docker Desktop, and your system uses default NAT networking, you must manually proxy incoming Windows traffic to the WSL virtual machine using the native Windows netsh utility.
Open PowerShell as an Administrator on Windows and set up the port proxy rule:
PowerShell
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.25.16.1
Replace 172.25.16.1 with the actual WSL IP returned by your terminal.
Allow Incoming Connections Through Windows Firewall
Even with Docker port publishing and network forwarding configured, Windows Defender Firewall will block incoming traffic arriving from external LAN devices unless an explicit inbound rule allows it.
To open a specific port for incoming traffic, open PowerShell as an Administrator and create a firewall rule:
PowerShell
New-NetFirewallRule -DisplayName “WSL Docker Port 3000” -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000
For systems running Mirrored Networking Mode, Hyper-V virtual firewall rules manage traffic entry points. To permit inbound connections on a specific port under mirrored mode, execute:
PowerShell
New-NetFirewallHyperVRule -Name “WSL-Docker-Port-3000” -DisplayName “WSL Docker Port 3000” -Direction Inbound -Protocol TCP -LocalPorts 3000
Security considerations: Avoid turning off your host firewall entirely. Restrict inbound rules specifically to the port your service requires, and ensure your active network profile is set to Private when working on trusted networks.
Access the Docker Container From Another Device
With networking and firewall configurations active, locate your host computer’s local IP address. Open PowerShell or Command Prompt and run:
PowerShell
ipconfig
Locate your active network connection and note the IPv4 Address, which will look similar to 192.168.1.100.
To connect from another device on the same network:
- Open a web browser or client application on the second device.
- Enter the full host IP address along with the published port: http://192.168.1.100:3000
- The request will pass through your Windows physical network card, hit the configured proxy or mirrored stack, and load your containerized application.
Do not attempt to use the internal WSL IP on external devices, as that private IP address is non-routable on your physical router network.
Troubleshoot Docker Ports That Still Do Not Work
If your service remains unreachable from other network devices, check these common failure points:
- Works on localhost, fails on local network: This confirms the container itself is healthy. The issue lies with your Windows firewall blocking incoming connections or missing port proxy configurations. Verify that your inbound firewall rule specifies the correct local port.
- Connection refused error immediately: The packet is reaching Windows, but no service is bound to that port. Run docker ps inside WSL to ensure the container is up and that the port mapping syntax matches your target port.
- Port forwarding stopped working after rebooting: Your WSL 2 machine changed its dynamic IP address upon restarting. Remove the outdated netsh rule and re-add it using the newly assigned WSL IP address.
- Mirrored mode settings do not take effect: Ensure you ran wsl –shutdown in PowerShell after modifying .wslconfig. Configuration edits do not apply to currently active WSL instances without a complete shutdown.
- Docker Desktop conflicts with manual setups: If you run both Docker Desktop and a manual Docker Engine daemon inside the same Linux distribution, port bindings will conflict. Choose one environment to manage your container runtimes.




