- 4 minutes read

We're living in crazy times. Nowadays, it's possible to run Linux applications on Windows. But when you add Docker to the equation, many people run into trouble with the local networks. Either they can access the server running in Docker, or the Docker container can't access a server running on Windows or WSL2. The latter proved to be a challenging problem. In a standard Linux installation, you can solve the problem by adding the parameter --net="host", but that doesn't seem to work on Windows.

Calling a web or REST service running in Docker

Let's start with the easy one because it's the more frequent use-case. You've started a service in a Docker container. For illustration purposes, let's use

docker run -P -p 8080:80 -d nginxdemos/hello

If you've installed a Linux distribution on WSL2 and activated the WSL2 integration of Docker for Windows, the server runs inside the WSL. In theory, now it's available on http://localhost:8080, no matter if you run a curl from the WSL command line or if you open a Windows browser.

Only sometimes it doesn't. That's strange, because according to the WSL documentation, you can configure this in the .wsl-config file. By default every WSL2 service running on localhost should be available on the same address from Windows, too.

If it doesn't, run the command ip -4 -c addr in a WSL shell. Now you should see something like this:

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 4: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 inet 172.17.46.186/28 brd 172.17.46.191 scope global eth0 valid_lft forever preferred_lft forever

We see two networks. We're interested in the second network, starting with 4: eth0. Note that the numbers may be different on your machine, depending on your network setup. The IP address behind inet: is used to expose services provided by the WSL to the Windows host. In other words, our service is available on http://172.17.46.186:8080.

There's a catch: the IP address changes frequently. You have to run ip addr after every reboot.

Calling a web or REST service from Docker

Sometimes you've got a Docker image accessing a web or REST server on your machine. That server runs on - say - localhost:8080, so it comes as a surprise that the Docker container can't call this address. You can check this by opening a shell in your Docker container and doing a curl request:

docker exec -it /bin/bash curl http://localhost:8080

That's a security feature. You don't want any Docker container to access your host network. Linux allows you to ignore this restriction by adding the parameter --net="host" to the Docker command. Docker for Windows doesn't seem to support this feature properly.

If you've started your server on the Windows host, you're in bad luck. I don't know how to access it. However, if you've run the server on WSL, you can access it using the address you've found out by running the command ip -4 -c addr, as I've described above. Only you can't. It works on some machines but fails on others.

Let's draw a little picture to understand what's going on:

For some reason, Docker uses the IP range 172.17.0.0/16 for internal network by default. That means the container can't access external addresses in this IP range. Unfortunately, WSL2 uses this address range, too. Docker in the address range blocks the address we've found using ip addr.

In my case, the solution was to configure Docker for Windows to use a different IP address range. Add this line to the Docker daemon configuration file:

"bip": "192.168.200.1/24"

Side effects

I'm not sure if it's related, but after modifying the Docker IP range, I couldn't access the WSL2 servers on http://localhost. However, it's still possible to access them using the WSL2 IP address. That's just a bit cumbersome because it changes so often. It's also possible to install and start a browser inside WSL2. Then it's possible to use http://localhost again.

Wrapping it up

Kudos go to Dmitry Yakovlev who's posted the solution on https://github.com/docker/for-win/issues/9168#issuecomment-771971994.


Comments