5

I am running a Windows Container on a Windows host (Windows Server 2016 TP4).

The container shall run an IIS webserver on port 80 internally and I also want to bind port 80 to the host, so I can reach it via the host IP/URL.

I followed the instructions from Microsoft on

I tried both the approach via Powershell and Docker, and in both cases, the port binding to the host does not work.

========================= Powershell approach ==========================

Deploying container host to existing system (Windows Server 2016 TP4)

PS C:> wget -uri https://aka.ms/tp4/Install-ContainerHost -OutFile C:\Install-ContainerHost.ps1

PS C:> powershell.exe -NoProfile C:\Install-ContainerHost.ps1

Querying status of Windows feature: Containers...
Feature Containers is already enabled.
Waiting for Hyper-V Management...
Networking is already configured.  Confirming configuration...
Getting Container OS image (NanoServer) version 10.0.10586.0 from OneGet (this may take a few minutes)...
Container base image install complete.  Querying container images...
OS image (NanoServer) is already installed.
The following images are present on this machine:
    ContainerImage (Name = 'NanoServer') [Publisher = 'CN=Microsoft', Version = '10.0.10586.0']
    ContainerImage (Name = 'WindowsServerCore') [Publisher = 'CN=Microsoft', Version = '10.0.10586.0']

Docker is already installed.
Stopping Docker...
Starting Docker...
Tagging new base image (8572198a60f1)...
Base image is now tagged:
nanoserver          10.0.10586.0        8572198a60f1        5 months ago        0 B
nanoserver          latest              8572198a60f1        5 months ago        0 B
Script complete!

Preparing image and container that runs IIS (based on WindowsServerCore image)

These are the exact steps described in the Microsoft documentation at https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/manage_powershell. I create a container from WindowsServerCore, install IIS on it, and make a new image out of it, which I can then later reuse.

PS C:> Get-ContainerImage

Name              Publisher    Version      IsOSImage
----              ---------    -------      ---------
NanoServer        CN=Microsoft 10.0.10586.0 True
WindowsServerCore CN=Microsoft 10.0.10586.0 True


PS C:\> New-Container -Name TP4Demo -ContainerImageName WindowsServerCore -SwitchName "Virtual Switch"

Name    State Uptime   ParentImageName
----    ----- ------   ---------------
TP4Demo Off   00:00:00 WindowsServerCore


PS C:\> Get-Container

Name    State Uptime   ParentImageName
----    ----- ------   ---------------
TP4Demo Off   00:00:00 WindowsServerCore


PS C:\> Start-Container -Name TP4Demo

PS C:\> Enter-PSSession -ContainerName TP4Demo -RunAsAdministrator
[TP4Demo]: PS C:\Windows\system32> Install-WindowsFeature web-server

Success Restart Needed Exit Code      Feature Result
------- -------------- ---------      --------------
True    No             Success        {Common HTTP Features, Default Document, D...


[TP4Demo]: PS C:\Windows\system32> exit
PS C:\> Stop-Container -Name TP4Demo

PS C:\> New-ContainerImage -ContainerName TP4Demo -Name WindowsServerCoreIIS -Publisher Demo -Version 1.0

Name                 Publisher Version IsOSImage
----                 --------- ------- ---------
WindowsServerCoreIIS CN=Demo   1.0.0.0 False


PS C:\> Remove-Container -Name TP4Demo -Force

Now I have an IIS container ready that I bind to the "Virtual Switch".

PS C:\> New-Container -Name IIS -ContainerImageName WindowsServerCoreIIS -SwitchName "Virtual Switch"

Name State Uptime   ParentImageName
---- ----- ------   ---------------
IIS  Off   00:00:00 WindowsServerCoreIIS


PS C:\> Start-Container -Name IIS

PS C:\> Invoke-Command -ContainerName IIS {ipconfig}

Windows IP Configuration

Ethernet adapter vEthernet (Virtual Switch-30179F35-A9BD-4231-B264-BDD2994BD956-0):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::24f4:c726:ed9b:e603%28
   IPv4 Address. . . . . . . . . . . : 172.16.0.2
   Subnet Mask . . . . . . . . . . . : 255.240.0.0
   Default Gateway . . . . . . . . . : 172.16.0.1

Adding port mapping and firewall rule:

PS C:\> if (!(Get-NetNatStaticMapping | where {$_.ExternalPort -eq 80})) {Add-NetNatStaticMapping -NatName "ContainerNat" -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 172.16.0.2 -InternalPort 80 -ExternalPort 80}

PS C:\> if (!(Get-NetFirewallRule | where {$_.Name -eq "TCP80"})) {New-NetFirewallRule -Name "TCP80" -DisplayName "HTTP on TCP/80" -Protocol tcp -LocalPort 80 -Action Allow -Enabled True}

Now that I added the port mapping (and firewall rule), I should be able to reach the IIS through my host. (Just to be sure, I disabled the firewall on the host entirely.)

But the host port binding does not work. I cannot reach the IIS through the host IPs and bound port via http://localhost:80/ nor http://172.16.0.1:80/ nor http://10.10.0.79:80/

PS C:\> wget http://10.10.0.79:80/
wget : Unable to connect to the remote server
At line:1 char:1
+ wget http://10.10.0.79:80/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

PS C:\> wget http://172.16.0.1:80/
wget : Unable to connect to the remote server
At line:1 char:1
+ wget http://172.16.0.1:80/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

I can only reach the IIS default page via the container IP (http://172.16.0.2:80).

========================= Docker approach ==========================

And this is my approach using Docker to manage the container:

C:\> docker run --name iisbase -it windowsservercore cmd
C:\> powershell.exe Install-WindowsFeature web-server
C:\> exit
PS C:\Windows\system32> docker commit iisbase windowsservercoreiis
64271b60a1c4af29ce37ebcee45b00d824883eb67c717d4cee765d9f696867bb
C:\> powershell.exe "if(!(Get-NetFirewallRule | where {$_.Name -eq 'TCP80'})) { New-NetFirewallRule -Name 'TCP80' -DisplayName 'HTTP on TCP/80' -Protocol tcp -LocalPort 80 -Action Allow -Enabled True }"
C:\> docker run --name iisdemo -it -p 80:80 windowsservercoreiis cmd

At the end, I can only reach the IIS via the container IP, not via the host IP.

I'm using Docker version 1.10.0-dev, build 18c9fe0.

1

2 Answers 2

1

Seems to be an issue with Windows Server TP4.

Stefan Scherer from the Docker team replied to my reported issue: https://github.com/docker/docker/issues/21558#issuecomment-202536462

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.

Waiting for TP5... meanwhile I use Apache httpd on the host to handle the port forwarding.

4
  • TP5 should be available in about 7 hours, shouldn't it? Commented Mar 30, 2016 at 8:23
  • @FalcoAlexander I don't know, where did you get that info from? Also interested about the release date. I googled for it, saw twitter.com/wzornet/status/701532616839847937 which is already passed. Commented Mar 30, 2016 at 8:26
  • 1
    The Build 2016 (in SF) conference starts in 7 hours. this is usually an event to distribute new releases. I guess: VisualStudio and TFS 2015 Update 2, new Windows 10 Release 1603 and Server 2016 TP5. Commented Mar 30, 2016 at 8:37
  • my bad...wrong speculations... :/ Commented Apr 2, 2016 at 9:59
0
+50

Note: Finally this is found to be a bug in Windows Server 2016 TP4 that causes the behavior described below (see the comments). Even though the Docker Daemon is supposedly installed, the client seems to be used instead with all the limitations described below. This bug may be fixed in the future TP5.


This is a limitation of the Docker implementation on Windows, where you cannot connect to the container through the host.

This is the answer for this same question on bug report #15740 : port exposure on windows = ? :

The reason you're having this, is because on Linux, the docker daemon (and your containers) run on the Linux machine itself, so "localhost" is also the host that the container is running on, and the ports are mapped to.

On Windows (and OS X), the docker daemon, and your containers cannot run natively, so only the docker client is running on your Windows machine, but the daemon (and your containers) run in a VirtualBox Virtual Machine, that runs Linux.

To connect to the container, you must connect to the IP-address of the virtual machine, not of your Windows computer.

This is all described in the Windows installation documentation, found here; http://docs.docker.com/installation/windows/.

The Virtual Machine is described in this section;
http://docs.docker.com/installation/windows/#learn-the-key-concepts-before-installing

And an explanation on how to map ports, and connect to them is explained here;
http://docs.docker.com/installation/windows/#container-port-redirection

I'm going to close this issue, because this is not a bug, and explained in the documentation. I hope the above explanation helps you.

19
  • 1
    Thanks for the link, but the linked github ticket refers to Windows 7 (or any Windows Server prior to Windows 2016), and the ticket reply says: "On Windows (and OS X), the docker daemon, and your containers cannot run natively, so only the docker client is running on your Windows machine, but the daemon (and your containers) run in a VirtualBox Virtual Machine, that runs Linux."; this is valid for Windows7, but this should not be the case for Windows 2016, where containers can run natively. Commented Mar 27, 2016 at 15:42
  • 1
    Also note the comment by thaJeztah on the github page you linked to: "Work is in progress to run Docker Engine natively on Windows Server 2016, but that engine will only run Windows applications, not Linux" <- this is what I am trying to do and using. Commented Mar 27, 2016 at 15:47
  • But you are asking about Docker which is not developed by Microsoft. For seamless integration with Windows, you should be using Windows technology which is Windows Containers and Hyper-V Containers, not Docker.
    – harrymc
    Commented Mar 27, 2016 at 16:55
  • I know Docker is not developed by MS, I use it for Linux Containers without problems. Per Microsoft documentation, Docker should work on Win2016 the same way as Windows containers. I am explicitly avoiding Hyper-V in order to not have a VM in between. I will give the Windows Containers approach a try but would prefer to use Docker since its what I use outside of the Windows world as well. Commented Mar 27, 2016 at 17:01
  • The differences will surely disappear in the future. For the current situation, see for example this article : Docker Engine for Windows Server 2016. I would guess that Microsoft should be gunning for total integration with Docker, maybe even in the release version of WS2016.
    – harrymc
    Commented Mar 27, 2016 at 17:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .