Containers Advanced

Resolving Docker `network_mode: host` and Port Mapping Issues on Windows WSL2 Ubuntu

Struggling with Docker containers in WSL2 not accessible from Windows? Understand why `network_mode: host` behaves differently and how to correctly map ports for your services.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Struggling with Docker containers in WSL2 not accessible from Windows? Understand why `network_mode: host` behaves differently and how to correctly map ports for your services.

When working with Docker containers within a Windows Subsystem for Linux 2 (WSL2) Ubuntu environment, developers and system administrators often encounter perplexing networking behavior, especially concerning host port mappings. A common scenario involves services that appear to run correctly within the WSL2 instance but remain inaccessible from the Windows host, leading to confusion about Docker's network_mode: host setting or standard port forwarding (-p). This guide will demystify these interactions, providing a clear path to successful port mapping and service accessibility.

Symptom & Error Signature

The primary symptom is a lack of connectivity to Docker containers from the Windows host, even when port mappings are configured or network_mode: host is specified. There is no explicit error message, but rather a silent failure to connect:

  • You run a Docker container inside your WSL2 Ubuntu distribution, e.g., an Nginx server listening on port 80.
  • You configure it with -p 8080:80 or ports: - "8080:80" in docker-compose.yml, or you use network_mode: host.
  • Inside the WSL2 Ubuntu terminal, curl localhost:80 (if network_mode: host) or curl localhost:8080 (if explicit mapping) works.
  • From your Windows PowerShell or Command Prompt, curl localhost:8080 (or the corresponding port) results in:
    curl : Unable to connect to the remote server
    curl : A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
    
  • Alternatively, if you're attempting to access a network_mode: host container from Windows via the WSL2 VM's IP, it also fails unless explicit port forwarding is handled by Docker Desktop (which it doesn't for network_mode: host containers by default).

Essentially, your container-exposed services are not reachable on localhost from the Windows host as expected, despite Docker appearing to run normally.

Root Cause Analysis

The core of this issue lies in understanding the architectural separation between the Windows host and the WSL2 environment, and how Docker Desktop integrates with it.

  1. WSL2 is a Lightweight Virtual Machine: WSL2 is not merely a compatibility layer; it runs a genuine Linux kernel inside a lightweight virtual machine. This VM has its own isolated network namespace, distinct from the Windows host's network. It receives a dynamically assigned internal IP address from Windows.

  2. Docker Desktop's WSL2 Integration: When you install Docker Desktop on Windows and enable WSL2 integration for your Ubuntu distribution, Docker Desktop does not run its daemon directly on Windows and expose it to WSL2. Instead, it installs and runs a dedicated Docker daemon inside a special WSL2 distribution (e.g., docker-desktop or docker-desktop-data). Your user-facing Ubuntu distribution then uses the Docker CLI to communicate with this daemon via a Unix socket, typically /var/run/docker.sock.

  3. network_mode: host in WSL2 Context: This is the most crucial point of confusion.

    • The network_mode: host directive tells the Docker daemon to attach the container's network stack directly to the network stack of the host where the daemon is running.
    • Since the Docker daemon is running inside the WSL2 VM, when you use network_mode: host within your WSL2 Ubuntu distribution, the container's ports are exposed directly on the WSL2 VM's IP address and network interfaces, not the Windows host's IP address or interfaces.
    • Consequently, localhost for a network_mode: host container within WSL2 refers to the WSL2 VM's localhost (127.0.0.1) and its internal IP address, making it inaccessible directly from localhost on the Windows host.
  4. Docker Desktop's Role in Port Forwarding: For standard port mappings (-p HOST_PORT:CONTAINER_PORT or ports: in Docker Compose), Docker Desktop automatically handles the necessary network address translation (NAT) and port forwarding. It listens on localhost:HOST_PORT on the Windows host and forwards traffic to WSL2_VM_IP:HOST_PORT, which then forwards it to the container. This automatic forwarding does not apply to containers configured with network_mode: host.

In summary, network_mode: host inside WSL2 does exactly what it's supposed to do—it uses the host's network—but that "host" is the WSL2 VM, not your Windows machine.

Step-by-Step Resolution

The resolution involves correctly understanding and configuring port mappings, rather than relying on network_mode: host for cross-OS accessibility.

1. Verify Docker Desktop WSL2 Integration

Ensure Docker Desktop is running and that your target Ubuntu distribution is enabled for integration.

  1. Start Docker Desktop: Make sure the Docker Desktop application is running on your Windows machine.

  2. Check WSL2 Integration:

    • Open Docker Desktop Settings.
    • Navigate to "Resources" -> "WSL Integration".
    • Ensure your Ubuntu distribution is toggled "On".

    If Docker Desktop is not running or WSL2 integration is disabled for your specific Ubuntu distribution, Docker commands run within that distribution will fail or use a different (potentially Windows-based) Docker daemon.

2. Avoid network_mode: host for Windows Host Accessibility

Unless you specifically intend for your container to be accessible only within the WSL2 VM's network namespace (e.g., for inter-container communication within that WSL2 instance, without Windows access), do not use network_mode: host.

network_mode: host is generally not the recommended way to expose services from WSL2 containers to the Windows host. Its primary use cases are for very specific networking scenarios within the Linux VM itself, such as:

  • Containers needing to sniff host traffic (of the WSL2 VM).
  • Containers that need to bind to specific host interfaces (of the WSL2 VM).

3. Implement Explicit Port Mappings

This is the correct and reliable method to make your Docker containers running in WSL2 accessible from your Windows host.

For docker run commands:

Use the -p flag to map a port on the Windows host to a port inside your container.

# Example: Run an Nginx container, mapping Windows host port 8080 to container port 80
docker run -d --name my-nginx -p 8080:80 nginx:latest
  • 8080: The port on your Windows host (accessible via localhost:8080).
  • 80: The port the Nginx server listens on inside the container.
For docker-compose.yml files:

Use the ports directive under your service definition.

# docker-compose.yml
version: '3.8'
services:
  web:
    image: nginx:latest
    container_name: my-nginx-compose
    ports:
      - "8080:80" # Map Windows host port 8080 to container port 80
    # networks: # Optional: If you use custom networks, define them here
    #   - my_bridge_network
# networks:
#   my_bridge_network:
#     driver: bridge

Then, run your Compose stack:

docker-compose up -d

Docker Desktop automatically handles the necessary port forwarding from the dynamically assigned WSL2 VM IP to localhost on the Windows host when you use -p or ports. You do not need to manually configure netsh rules or other port forwarding within Windows.

4. Test Connectivity from Windows

After applying explicit port mappings, verify connectivity directly from your Windows host.

  1. Open PowerShell or Command Prompt on Windows.

  2. Attempt to connect:

    curl http://localhost:8080
    

    or, for a more robust check:

    Test-NetConnection -ComputerName localhost -Port 8080
    

    You should see a successful connection response (e.g., Nginx welcome page HTML for curl, or TcpTestSucceeded : True for Test-NetConnection).

5. Address Potential Firewall Conflicts (Windows Defender)

While Docker Desktop usually configures Windows Defender Firewall rules automatically, issues can sometimes arise.

  1. Check Windows Defender Firewall:

    • Search for "Windows Defender Firewall with Advanced Security".
    • Navigate to "Inbound Rules".
    • Look for rules related to Docker Desktop or specific ports (e.g., "Docker Desktop WSL2" or similar entries). Ensure they are enabled and permit connections on the host port you're trying to use (e.g., 8080).
    • If you're using a third-party firewall, consult its documentation to ensure it's not blocking localhost traffic or the specific port.

    Do not indiscriminately disable your firewall. Only create specific rules for known services and ports, or temporarily disable for diagnosis in a secure environment.

  2. WSL2 Internal Firewall (UFW): The ufw firewall inside your Ubuntu WSL2 distribution typically does not interfere with Docker's networking, as Docker manages its own iptables rules. However, if you have explicitly configured ufw to block ports, it could impact communication within the WSL2 VM. Usually, this isn't the cause of Windows-to-WSL2 port forwarding issues managed by Docker Desktop.

6. Restart Docker Desktop and WSL2

If you've made changes and are still experiencing issues, a restart can often resolve transient networking glitches.

  1. Restart Docker Desktop: Right-click the Docker icon in the Windows system tray and select "Restart Docker Desktop".
  2. Restart WSL2:
    • Open PowerShell or Command Prompt as Administrator.
    • Shut down all WSL2 distributions:
      wsl --shutdown
      
    • Restart your specific Ubuntu distribution:
      wsl -d Ubuntu # Replace 'Ubuntu' with your distro name if different
      
    • Alternatively, just close all WSL2 terminal windows and reopen them, Docker Desktop should re-initialize its WSL2 backend.

Conclusion

The "Docker network host port mapping ignored" issue on Windows WSL2 Ubuntu is almost always a misunderstanding of how network_mode: host interacts with the WSL2 VM's isolation and Docker Desktop's port forwarding capabilities. By consistently using explicit port mappings (-p or ports) and ensuring Docker Desktop's WSL2 integration is active, you can reliably expose your containerized services from WSL2 to your Windows host. Remember that network_mode: host applies to the WSL2 VM, not your Windows machine.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.