windows wsl docker port to network​

How to Expose Docker Ports to Your Local Network in WSL

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:

  1. Open a web browser or client application on the second device.
  2. Enter the full host IP address along with the published port: http://192.168.1.100:3000
  3. 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.