moby: Windows Container port binding not working on Windows Server 2016 TP4 (using Docker)

Environment:

Windows Server 2016 TP4 Docker version 1.10.0-dev, build 18c9fe0

Original detailed problem description:

http://superuser.com/questions/1057223/windows-container-port-binding-on-windows-server-2016-not-working

Issue:

I am running a Windows container using Docker on a Windows host (Windows Server 2016 TP4).

Note that I am using Windows Server 2016 (not any prior Windows version), where Windows Containers can run natively without an intermediate VM (no docker machine there) using Docker.

I followed the instructions on https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/inplace_setup to setup the Windows container host (bare metal host, no Hyper-V, no VM).

Specifically, this powershell script provided by Microsoft was executed to setup the Windows 2016 container host https://aka.ms/tp4/Install-ContainerHost, where it seems that all prerequisites regarding networking seem to be done. Inside the container runs an IIS web server on the internal port 80.

I want to bind it to the host port 8800.

I followed the instruction as per:

https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/manage_docker#create-iis-image-1-

and ran the container like this:

docker run --name iisdemo -it -p 8800:80 windowsservercoreiis cmd

and had also added the firewall rules as per https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/manage_docker#configure-network for ports 80 and 8800 beforehand. But I also turned off the Windows Firewall on the host entirely for testing purposes, just to be sure it’s not conflicting.

As you can see from above docker call, I just made a slight change to the example given on the documentation page and changed the bound host port from 80 to 8800, so instead of -p 80:80 I run -p 8800:80.

When I run “ipconfig” on both host and container, I get:

  • Host IP: 172.16.0.1
  • Container IP: 172.16.0.2

I am either having a misunderstanding what the host is or something does not work right.

The documentation says:

When the container has been created, open a browser, and browse to the IP address of the container host. Because port 80 (in my case it’s 8800) of the host has been mapped to port 80 of the container, the IIS splash screen should be displayed. Unfortunately, this does not work.

I can reach the IIS via the container IP: http://172.16.0.2:80 but not via the host IP address http://172.16.0.1:8800.

(I also tried -p 80:80, and also that does not work; I cannot reach 172.16.0.1:80).

Running a docker port iisdemo returns nothing:

PS C:\Windows\system32> docker port iisdemo
PS C:\Windows\system32>

and also docker ps does not show anything under “ports”.

docker inspect iisdemo shows me:

"PortBindings": {
    "80/tcp": [
        {
            "HostIp": "",
            "HostPort": "8800"
        }
    ]
},
...
"ExposedPorts": {
    "80/tcp": {}
},

From my understanding, since I run docker “natively” from a Windows server with a Windows container, there is no intermediate VM (no docker machine) in between, so the “host” is the actual Windows Server that I run docker on.

So my question is, why does the host port binding not work? Why can I not reach the host as per Microsoft documentation?

What I also find confusing is that when I run netstat on both the host and the container, I get the same results! netstat on the host does not show port 8800, but it does show port 80, which should imho only appear when running netstat in the container.

netstat on Host:

C:\>netstat -ab | findstr ":80"
  TCP    0.0.0.0:80             test2016:0             LISTENING
C:\>netstat -ab | findstr ":8800"
C:\>

netstat on Container:

C:\>netstat -ab | findstr ":80"
  TCP    0.0.0.0:80             test2016:0             LISTENING
  TCP    [::]:80                test2016:0             LISTENING
C:\>netstat -ab | findstr ":8800"
C:\>

And when I stop the container, the port 80 does not show anymore when I run netstat on the host. Why? It seems as if the network interfaces of host and container are the same.

I also read the documentation about NAT networking mode, although I must say, I am not a network expert. https://msdn.microsoft.com/en-us/virtualization/windowscontainers/management/container_networking#port-mapping

I am not sure though whether this is relevant or not regarding the “Getting started: IIS demo”, since it’s not mentioned there or linked to at all. (I did not run any configuration commands mentioned there.) From my understanding, it should only be relevant for port forwarding when requesting from the host from an external IP address.

FYI - this is what I get when I run some Powershell commands about the virtual switch information on my host:

PS C:> Get-VMSwitch

Name           SwitchType NetAdapterInterfaceDescription
----           ---------- ------------------------------
Virtual Switch NAT

PS C:> Get-NetNatStaticMapping

StaticMappingID               : 16
NatName                       : ContainerNAT
Protocol                      : TCP
RemoteExternalIPAddressPrefix : 0.0.0.0/0
ExternalIPAddress             : 0.0.0.0
ExternalPort                  : 80
InternalIPAddress             : 172.16.0.2
InternalPort                  : 80
InternalRoutingDomainId       : {00000000-0000-0000-0000-000000000000}
Active                        : True
and this is what I get with ipconfig on host and container:

ipconfig (Container):

PS C:\Windows\system32> ipconfig

Windows IP Configuration

Ethernet adapter vEthernet (Virtual Switch-897f61a2cf88f8403d2e1bc946ef76710ac2540882b31b030445781fcf5eca25-0):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::944:73e2:2d58:7c33%26
   IPv4 Address. . . . . . . . . . . : 172.16.0.2
   Subnet Mask . . . . . . . . . . . : 255.240.0.0
   Default Gateway . . . . . . . . . : 172.16.0.1

ipconfig (Host):

PS C:\Windows\system32> ipconfig

Windows IP Configuration

Ethernet adapter Ethernet0:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::19a9:f8bf:6e6d:5544%4
   IPv4 Address. . . . . . . . . . . : 10.10.0.79
   Subnet Mask . . . . . . . . . . . : 255.255.254.0
   Default Gateway . . . . . . . . . : 10.10.0.1

Ethernet adapter vEthernet (Virtual Switch):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::cc17:6b74:4fab:ecce%3
   IPv4 Address. . . . . . . . . . . : 172.16.0.1
   Subnet Mask . . . . . . . . . . . : 255.240.0.0
   Default Gateway . . . . . . . . . :

Tunnel adapter isatap.{0DADB974-F583-4B51-B4B0-C7526A8BABAD}:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Tunnel adapter isatap.{0D2767F2-FF2B-4D79-B338-94722C2CF8F9}:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

For testing purposes, I just installed an Apache httpd server on the Windows 2016 host and let it run on port 80, in order to block port 80 there.

Then I run

docker run --name iisdemo -it -p 80:80 windowsservercoreiis cmd

to see if it conflicts (which I expected) due to the port 80 already being in use, but it does not!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 31 (10 by maintainers)

Most upvoted comments

Port binding is not working for me in TP5. Tried from a different host and same issue. Not sure whats wrong.

netstat -an does not show any listening port after running docker run with port binding 80:80.

docker inspect shows the below.

PS C:\Windows\system32> docker inspect 4b145d28211d [ { “Id”: “4b145d28211d5a74e754ea3c16fe02022d625d1b806bbe1668486d2f07f9d66c”, “Created”: “2016-06-15T08:55:03.7827423Z”, “Path”: “cmd”, “Args”: [], “State”: { “Status”: “running”, “Running”: true, “Paused”: false, “Restarting”: false, “OOMKilled”: false, “Dead”: false, “Pid”: 5692, “ExitCode”: 0, “Error”: “”, “StartedAt”: “2016-06-15T08:55:09.7229827Z”, “FinishedAt”: “0001-01-01T00:00:00Z” }, “Image”: “sha256:c26f4ceb81db654e32b509dd632c3dbca15f8be14d29606de465f2ba8a61045e”, “ResolvConfPath”: “”, “HostnamePath”: “”, “HostsPath”: “”, “LogPath”: “C:\ProgramData\docker\containers\4b145d28211d5a74e754ea3c16fe02022d625d1b806bbe1668486d2f07f9d66c\4b1 45d28211d5a74e754ea3c16fe02022d625d1b806bbe1668486d2f07f9d66c-json.log”, “Name”: “/stupefied_pike”, “RestartCount”: 0, “Driver”: “Windows filter storage driver”, “MountLabel”: “”, “ProcessLabel”: “”, “AppArmorProfile”: “”, “ExecIDs”: null, “HostConfig”: { “Binds”: null, “ContainerIDFile”: “”, “LogConfig”: { “Type”: “json-file”, “Config”: {} }, “NetworkMode”: “default”, “PortBindings”: { “80/tcp”: [ { “HostIp”: “”, “HostPort”: “80” } ] },

Tried installing docker container through the poweshell script provided by MS. But still no go.

It doesn’t work remotely either. It just flat out isn’t working.

On Sun, Nov 6, 2016 at 4:17 AM -0700, “Michael Friis” notifications@github.com wrote:

@rayterrill @panmanphil Yeah, I think this is a known limitation of the current implementation: https://blog.sixeyed.com/published-ports-on-windows-containers-dont-do-loopback/

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

@StefanScherer is there a reason why docker run -d -p 80:80 microsoft/iis:nanoserver works but docker run -d -p 8000:80 microsoft/iis:nanoserver does not? That is that I can’t access port 8000 on the NAT IP, but i can access it on port 80

I have EXPOSE 80 in my Dockerfile which lists the available ports in my container but the port mapping doesn’t seem to work.

Seems that port mapping on Windows does not work (I am using Windows 10 Pro however, not Windows Server 2016)

https://github.com/Microsoft/Virtualization-Documentation/issues/181#issuecomment-234321612

I checked with the devs and they’re aware of the issue. It will be fixed before Windows Server 2016 is shipped, but unfortunately I don’t have a workaround for TP5.

@arnodenuijl Port binding in TP5 works fine for me, but just make sure that you’re making the requests from outside the container host, not from/to itself. See https://github.com/Microsoft/Virtualization-Documentation/issues/253

I can reproduce the problems of @mathiasconradt. Played with the voting-app last week with TP4, I have the same workaround: Opening firewall ports on the host, opening the web server url with container’s IP addresses. Can’t wait to test the voting-app on TP5.

@jhowardmsft I updated the original posting on StackExchange/SuperUser with all the steps in details that I did using the Powershell approach (but it does not work with the Docker approach either), following all the steps exactly from the Microsoft documentation.