My Windows Server 2016 host OS does not listen to the port that my container is mapped to

I am running Windows Server 2016 Version 1607 OS Build 14393.1480, and Docker version 17.03.1-ee-3 build 3fcee33. It is inside an ESXi. I have a problem where the host OS does not appear to be listening to a port that is mapped to a Docker port. In short terms, I can run a container with an Apache 2.4-server that works from the inside of the container, but is unreachable from the outside of the container. The host OS does not have any PID that listens on the appropriate mapped port of the container.

Details below. I have attached a simple screenshot inside the spoiler in case you think that is easier to read.

Dockerfile:

FROM nanoserver/apache24
EXPOSE 80

I run PowerShell on the host (Windows Server 2016). I build and run the container and try to reach the mapped port of my container.

PS C:\Users\Administrator\temp> docker build -f .\nanoserver-apache.dockerfile .
Sending build context to Docker daemon 26.11 kB
Step 1/2 : FROM nanoserver/apache24
 ---> 1a4664e93b81
Step 2/2 : EXPOSE 80
 ---> Running in bd93463646d9
 ---> 23a7cedc8ffa
Removing intermediate container bd93463646d9
Successfully built 23a7cedc8ffa
PS C:\Users\Administrator\temp> docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
<none>                <none>              23a7cedc8ffa        4 seconds ago       1.02 GB
nanoserver/iis        latest              4b0af9b7f036        3 months ago        1.15 GB
nanoserver/apache24   latest              1a4664e93b81        6 months ago        1.02 GB
PS C:\Users\Administrator\temp> docker run -di -p 8082:80 --name apache-experiment 23a7cedc8ffa
708624c1becca70ea3a8c4accdbff7360dffa131f59c6a515343e0dd9ea2420a
PS C:\Users\Administrator\temp> docker ps
CONTAINER ID        IMAGE               COMMAND                    CREATED             STATUS              PORTS
S
708624c1becc        23a7cedc8ffa        "c:\\windows\\system..."   21 seconds ago      Up 14 seconds       0.0.0.0:8082->80/tcp
he-experiment
PS C:\Users\Administrator\temp> docker inspect --format="{{.NetworkSettings.Networks.nat.IPAddress}}" apache-experiment
172.23.62.204
PS C:\Users\Administrator\temp> Invoke-WebRequest -uri http://localhost:8082
Invoke-WebRequest : Unable to connect to the remote server
At line:1 char:1
+ Invoke-WebRequest -uri http://localhost:8082
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
PS C:\Users\Administrator\temp> Invoke-WebRequest -uri http://172.23.62.204:8082
Invoke-WebRequest : Unable to connect to the remote server
At line:1 char:1
+ Invoke-WebRequest -uri http://172.23.62.204:8082
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
PS C:\Users\Administrator\temp> netstat -a -o
 
Active Connections
 
  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:80             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:135            HONNINGKRUKKE-WEB:0    LISTENING       688
  TCP    0.0.0.0:445            HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:2179           HONNINGKRUKKE-WEB:0    LISTENING       1828
  TCP    0.0.0.0:5985           HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30004          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30005          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30006          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30010          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30012          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30018          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30020          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30022          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30024          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30071          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30072          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30091          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:30101          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:47001          HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    0.0.0.0:49664          HONNINGKRUKKE-WEB:0    LISTENING       456
  TCP    0.0.0.0:49665          HONNINGKRUKKE-WEB:0    LISTENING       896
  TCP    0.0.0.0:49666          HONNINGKRUKKE-WEB:0    LISTENING       572
  TCP    0.0.0.0:49667          HONNINGKRUKKE-WEB:0    LISTENING       1016
  TCP    0.0.0.0:49668          HONNINGKRUKKE-WEB:0    LISTENING       1380
  TCP    0.0.0.0:49685          HONNINGKRUKKE-WEB:0    LISTENING       560
  TCP    172.23.48.1:53         HONNINGKRUKKE-WEB:0    LISTENING       1488
  TCP    172.23.48.1:139        HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:80                HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:135               HONNINGKRUKKE-WEB:0    LISTENING       688
  TCP    [::]:445               HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:2179              HONNINGKRUKKE-WEB:0    LISTENING       1828
  TCP    [::]:5985              HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30004             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30005             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30006             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30010             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30012             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30018             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30020             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30022             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30024             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30071             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30072             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30091             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:30101             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:47001             HONNINGKRUKKE-WEB:0    LISTENING       4
  TCP    [::]:49664             HONNINGKRUKKE-WEB:0    LISTENING       456
  TCP    [::]:49665             HONNINGKRUKKE-WEB:0    LISTENING       896
  TCP    [::]:49666             HONNINGKRUKKE-WEB:0    LISTENING       572
  TCP    [::]:49667             HONNINGKRUKKE-WEB:0    LISTENING       1016
  TCP    [::]:49668             HONNINGKRUKKE-WEB:0    LISTENING       1380
  TCP    [::]:49685             HONNINGKRUKKE-WEB:0    LISTENING       560
  UDP    0.0.0.0:123            *:*                                    228
  UDP    0.0.0.0:500            *:*                                    1016
  UDP    0.0.0.0:4500           *:*                                    1016
  UDP    0.0.0.0:5050           *:*                                    228
  UDP    0.0.0.0:5353           *:*                                    552
  UDP    0.0.0.0:5355           *:*                                    552
  UDP    0.0.0.0:56688          *:*                                    552
  UDP    0.0.0.0:64950          *:*                                    552
  UDP    127.0.0.1:1900         *:*                                    1408
  UDP    127.0.0.1:61936        *:*                                    1408
  UDP    172.23.48.1:53         *:*                                    1488
  UDP    172.23.48.1:137        *:*                                    4
  UDP    172.23.48.1:138        *:*                                    4
  UDP    172.23.48.1:1900       *:*                                    1408
  UDP    172.23.48.1:61934      *:*                                    1408
  UDP    [::]:123               *:*                                    228
  UDP    [::]:500               *:*                                    1016
  UDP    [::]:4500              *:*                                    1016
  UDP    [::]:5353              *:*                                    552
  UDP    [::]:5355              *:*                                    552
  UDP    [::]:56688             *:*                                    552
  UDP    [::]:64950             *:*                                    552
  UDP    [::1]:1900             *:*                                    1408
  UDP    [::1]:61933            *:*                                    1408
PS C:\Users\Administrator\temp>

I run in PowerShell inside the container and retrieve the Apache default document from localhost:80 (works like a charm):

PS C:\> Invoke-WebRequest -uri http://localhost:80
 
 
StatusCode        : 200
StatusDescription : OK
Content           : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                    <html xmlns="http://www.w3.org/1999/xhtml"><!--
                        Modified from the Debian...
RawContent        : HTTP/1.1 200 OK
                    Connection: Keep-Alive
                    Date: Thu, 20 Jul 2017 07:37:06 GMT
                    Keep-Alive: timeout=5, max=100
                    Accept-Ranges: bytes
                    ETag: "2553-5458890dfad00"
                    Server: Apache/2.4.25
 
                    <!DOCTYPE html ...
Forms             :
Headers           : {[Connection, System.String[]], [Date, System.String[]], [Keep-Alive, System.String[]], [Accept-Ranges,
                    System.String[]]...}
Images            : {@{outerHTML=<img src="images/nanologo.png" alt="Nano Server Logo" class="floating_element">; tagName=IMG;
                    src=images/nanologo.png; alt=Nano Server Logo; class=floating_element}, @{outerHTML=<img
                    src="images/valid-xhtml10.png" alt="Valid XHTML 1.0 Transitional" height="31" width="88">; tagName=IMG;
                    src=images/valid-xhtml10.png; alt=Valid XHTML 1.0 Transitional; height=31; width=88}}
InputFields       : {}
Links             : {@{outerHTML=<a href="#about">About</a>; tagName=A; href=#about}, @{outerHTML=<a href="#changes">Changes</a>;
                    tagName=A; href=#changes}, @{outerHTML=<a href="#scope">Scope</a>; tagName=A; href=#scope}, @{outerHTML=<a
                    href="#files">Config files</a>; tagName=A; href=#files}...}
ParsedHtml        :
RawContentLength  : 9555

I know the output is not very easy to read inside the “preformatted text” boxes, but I don’t know any other way to escape the URL localhost links. “New” users are not permitted more than two links per post. :expressionless: It’s easier if you copy and paste it into Notepad etc…

From https://github.com/Microsoft/iis-docker

With the current release, you can’t use http://localhost to browse your site from the container host. This is because of a known behavior in WinNAT, and will be resolved in future. Until that is addressed, you need to use the IP address of the container.

It has nothing to do with IIS, but with Windows Server 2016. You can use docker inspect to find out the IP address of your container.

I did use docker inspect to find the IP address of my container, and it was 172.23.62.204. 172.23.62.204:8082 fails to resolve, just like localhost:8082. Furthermore, as I wrote, there does not appear to be any PID in host OS that listens on the appropriate port, 8082. Is this weird, or is it to be expected? I’m considering to file this as a bug, but I’m not quite that confident yet.

You can not connect to mapped IP address within container host itself. it’s bug in Windows implementation of WinNAT. You need get private IP address of container and connect to it using port number.
Or you can access through public mapped port from another host on the same network, that shall work.
Also stop using netstat for anything. The way to go is super powerfull Get-nettcconnection

Get-NetTCPConnection -LocalPort 80

1 Like

Thank you so much! I had been losing sleep over this issue. I can connect to the container from another host on the same network. It never occurred to me that that might work.

I still don’t find any process on the host machine listening on port 8082, though (as I would expect there to be). Not that this really matters though now that it actually works.