New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker for windows is not mapping ports to localhost #204

Closed
panmanphil opened this Issue Nov 4, 2016 · 57 comments

Comments

Projects
None yet
@panmanphil
Copy link

panmanphil commented Nov 4, 2016

Expected behavior

Using a simple example of the FROM microsoft/iis and EXPOSE 8000 as shown in the samples, this type of command runs, and I can access the port on the ip address shown from docker inspect. However when I use port mapping like so:

docker run -d -p 8080:8000 --rm iissite

I expect to be able to access the site from http:/localhost:8080, instead only the nat ip and EXPOSE port are reachable.

Actual behavior

unable to connect

Information

  • Diagnostic ID from "Diagnose & Feedback" in the menu.
  • a reproducible case if this is a bug, Dockerfiles FTW
  • page URL if this is a docs issue or the name of a man page
  • host distribution and version (Windows version, build number, etc)
    Client:
    Version: 1.12.0
    API version: 1.24
    Go version: go1.6.3
    Git commit: 8eab29e
    Built: Thu Jul 28 23:54:00 2016
    OS/Arch: linux/amd64

Server:
Version: 1.12.2-cs2-ws-beta
API version: 1.25
Go version: go1.7.1
Git commit: 050b611
Built: Tue Oct 11 02:35:40 2016
OS/Arch: windows/amd64

windows version 1607 build 14393.351

Dockerfile
FROM microsoft/iis
RUN mkdir C:\site
RUN powershell -NoProfile -Command
Import-module IISAdministration;
New-IISSite -Name "Site" -PhysicalPath C:\site -BindingInformation "*:8001:"
EXPOSE 8001
ADD . /site

Steps to reproduce the behavior

docker run -d --name site iissite
(from powershell)
docker inspect --format='{{.NetworkSettings.Networks.nat.IPAddress}}' site
wget "http://:8001" -UseBasicParsing
You see StatusCode 200

docker stop site
docker rm site
docker run -d -p 8080:8001 --name site iissite
wget "http://localhost:8080" -UseBasicParsing

get "unable to connect to the remote server"
also try trying the ip of ethernet0 from ip config

with linux containers and previous version of docker for windows, this works and works well

@panmanphil

This comment has been minimized.

Copy link
Author

panmanphil commented Nov 5, 2016

Running the same type of -p option on Windows 2016 also does not work. On the Windows 2016 I tried all of the available ip addresses but only the address shown from docker inspect and the original port from the EXPOSE statement worked. I could swear this worked before, and have been doing this for all of this year with the linux/mac versions of docker.

@rn

This comment has been minimized.

Copy link
Contributor

rn commented Nov 5, 2016

@panmanphil thanks for the report. Probably confusing, but networking for Windows containers is done differently to the way we run Linux containers on Windows (and the Mac). For Linux containers we use a component, called VPNKit, which watches containers with exposed ports being created and exposes them on the localhost. For Windows containers this component is not used and containers and their ports are only accessible via the NATed IP address.

This is expected behaviour and I'm closing this issue. We should probably add this to our documentation (/cc @londoncalling).

@rn rn closed this Nov 5, 2016

@panmanphil

This comment has been minimized.

Copy link
Author

panmanphil commented Nov 6, 2016

This isn't just the loopback connector that isn't working. I tried all the ip addresses on the box listed from ipconfig, and none of them could be used to connect. Only the nated container ip address and port worked. What is the purpose of having -p then if not to put the port on one of the host's ip addresses?

Yes please do update the documentation, I can't be the first to spend a bunch of time on this.

@friism

This comment has been minimized.

Copy link

friism commented Nov 6, 2016

@panmanphil the containers are currently only available on the container IP:

 docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' <container>  

Details here: https://blog.sixeyed.com/published-ports-on-windows-containers-dont-do-loopback/

@Rusk85

This comment has been minimized.

Copy link

Rusk85 commented Apr 30, 2017

Is this still an issue. Because I tried it with the lastest version of Docker on Win10Pro and netstat -ap | grep PORT gave me nothing.

@jonstelly

This comment has been minimized.

Copy link

jonstelly commented May 13, 2017

This is still an issue but if/when it will be resolved seems murky. For anyone else that might be frustrated, I've put together an admittedly sub-optimal work-around for this limitation, DockerProxy. It's a dotnet core console app that proxies from localhost:{port} -> docker-container:{port}. It monitors docker and will start/stop listening on ports as containers come up or down.

@szydan

This comment has been minimized.

Copy link

szydan commented May 23, 2017

For me NATing the port in VirtualBox worked
Go to VirtualBox -> Your BOX -> Settings -> Network ->
Choose NAT
Open Advanced
Click Port Forwarding
Add new rule to map whatever port you need from host to guest
Click OK, OK
Then stop, start the BOX

@vguna

This comment has been minimized.

Copy link

vguna commented Jul 16, 2017

@jonstelly : thanks for the docker proxy. But it doesn't seem to work for me. I just start it on my Windows 7 Home like this:

D:\Coding\DockerProxy>dockerproxy
Hosting environment: Production
Content root path: D:\Coding\DockerProxy
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

Starting stopping docker image via docker on cmd line doesn't have any effect. I'm missing something here? I also don't understand why it is listening on 5000. Can it be remote controlled or something?

@vguna

This comment has been minimized.

Copy link

vguna commented Jul 18, 2017

Ok, I digged deeper into the rabbit hole and debugged/compiled my own version to see what's the problem here. Forget about the listening stuff I wrote :).

First of all, I have to run the docker tools (docker-machine) on my Windows 7. I think this is the main reason, that DockerProxy is not working out of the box. I did two things to make it work:

In Proxy.cs there something like var nat = Container.NetworkSettings.Networks["nat"];. This silently fails, because in my json there's only a "bridge". After changing that, it starts to bind to 172.17.0.2 - which doesn't work because with the docker-machine, the IP of the VM has to be used - 192.168.99.100 in my case. So for testing I just hardcoded the ip to it, and now it seems to work.

I think it should be possible to get that IP via docker-machine ip. Are there any plans to add docker-tools support to docker proxy?

@TouDick

This comment has been minimized.

Copy link

TouDick commented Sep 19, 2017

This is ridiculous...
I spent hours looking why my ports are not forwarded as in getting started guide and then I find this....

This should work out of the box! And this is still not mentioned in documentation or am I missing something?!

Moreover default machine created like in getting started guide is not NAT-ted so doing anything like docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' returns only

This issue should be reopened and fixed properly. Instead of avoiding the proper solution. This is at end what docker should just do without excuses. Why do anyone need docker container with no possibility to connect to it anyway?

Edit:
PS. docker-machine ip is best suited to get an IP of machine created with default options

@vguna

This comment has been minimized.

Copy link

vguna commented Sep 19, 2017

In the end I switched to Windows 10 Professional since this solution wasn't reliable :(. I wanted to avoid that at all costs. But docker and Win7 is a pain. With the native docker it works quite well now!

@joshijimit

This comment has been minimized.

Copy link

joshijimit commented Dec 16, 2017

The only way we can access exposed port in windows is through

> http://<docker-machine ip>:<exposed port>

. I have tried every ip address listed in my ipconfig -all list. At last I found the correct ip from command docker-machine ip. Worked for me in windows 10 pro.

@nickweavers

This comment has been minimized.

Copy link

nickweavers commented Dec 16, 2017

So, I have installed the http docker image

$docker run -d --name MyWebServer httpd
7d4f8eb312d1463fd67c7d9169c5bad17581c0d1f5b0319de8c9bfa32df06150

It's running

$docker ps -all
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
df3a451e696f        httpd               "httpd-foreground"   20 minutes ago      Up 20 minutes       80/tcp              MyWebServer

The dockerfile for this image exposes port 80:

EXPOSE 80
CMD ["httpd-foreground"]

When I look at the settings in my Window Docker I see:
image
But when I browse to 10.0.75.0
image

@nickweavers

This comment has been minimized.

Copy link

nickweavers commented Dec 16, 2017

I found this very good blog article where it explains how to get around this.

$docker run -d --name MyWebServer -P httpd
f552aa1667f351d63f1cf7e3dae7ab336837ca49c38838dc53c7f3c038dc5c88

Using the -P flag apparently assigns a randomised port number to expose. Reassuringly I saw a Windows Security Alert:
image

$docker port MyWebServer
80/tcp -> 0.0.0.0:32768

but, dissapointingly... http://10.0.75.0:32769 still gives me
image

@nickweavers

This comment has been minimized.

Copy link

nickweavers commented Dec 16, 2017

Thanks @joshijimit, I eventually tried your tip of trying all of the addresses given by ifconfig -a and one of them worked

wifi0     Link encap:UNSPEC  HWaddr 74-E5-43-A7-A0-A1-00-00-00-00-00-00-00-00-00-00
          inet addr:10.0.0.13  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::d96a:8316:a0d:20b3/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

image
I don't understand why the Docker settings panel tells my it's using 10.0.75.0 but the web server can only be reached on http://10.0.0.13:32769/

@joshijimit

This comment has been minimized.

Copy link

joshijimit commented Dec 16, 2017

Glad to hear it helps you @nickweavers. And yes I am also not sure why there is a conflict in IP address in Windows with docker.

@kallie-b

This comment has been minimized.

Copy link

kallie-b commented Dec 19, 2017

Hi all,

We now have support for using localhost/loopback to access your container's published ports on Windows 10! Here's the announcement for this support, which is available starting with Windows 10 Insider build 17025.

Have any of you been able to try this already? If so, we'd love to hear your feedback. Let us know whether or not this support is meeting your needs. Feel free to reply here with comments or email our team at sdn_feedback@microsoft.com.

--Kallie Bracken
PM, Windows Core/Container Networking at Microsoft

@joshijimit

This comment has been minimized.

Copy link

joshijimit commented Dec 20, 2017

Cool I will give it a try.. Thanks for update.

@nickweavers

This comment has been minimized.

Copy link

nickweavers commented Dec 22, 2017

nickw@DESKTOP-OREBB4V:~
$docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
f49cf87b52c1: Pull complete
02ca099fb6cd: Pull complete
de7acb18da57: Pull complete
770c8edb393d: Pull complete
0e252730aeae: Pull complete
6e6ca341873f: Pull complete
2daffd0a6144: Pull complete
Digest: sha256:b5f21641a9d7bbb59dc94fb6a663c43fbf3f56270ce7c7d51801ac74d2e70046
Status: Downloaded newer image for httpd:latest
nickw@DESKTOP-OREBB4V:~
$docker run -d --name MyWebServer httpd
9b100d3a54980d91745697e99f5771eb035d5b7d52d268a8dd044a00d77fbbdf
nickw@DESKTOP-OREBB4V:~
$curl localhost
curl: (7) Failed to connect to localhost port 80: Connection refused

Sadly not working
Lets try mapping dockerfile exposed port on the docker run command
First we need to cleanup

nickw@DESKTOP-OREBB4V:~
$docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS               NAMES
9b100d3a5498        httpd               "httpd-foreground"   About a minute ago   Up About a minute   80/tcp              MyWebServer
nickw@DESKTOP-OREBB4V:~
$docker stop 9b100d3a5498
9b100d3a5498
nickw@DESKTOP-OREBB4V:~
$docker rm 9b100d3a5498
9b100d3a5498

Now we can try again

nickw@DESKTOP-OREBB4V:~
$docker run -d --name MyWebServer -p 80:80 httpd
5162d436d3deea1ff5638ec3065787e479df668425c038c6262e246447cf7af1
nickw@DESKTOP-OREBB4V:~
$docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
5162d436d3de        httpd               "httpd-foreground"   7 seconds ago       Up 5 seconds        0.0.0.0:80->80/tcp   MyWebServer
nickw@DESKTOP-OREBB4V:~
$curl localhost
<html><body><h1>It works!</h1></body></html>

This time we're good, but is this what you meant by

We now have support for using localhost/loopback to access your container's published ports on Windows 10!

since there was no mention of having to use the -p flag?

@kimtso

This comment has been minimized.

Copy link

kimtso commented Dec 27, 2017

Hi, I am new on this stuff, could I know is the "exposed" work properly in microsof/iis?
Even I used ip of below, still cannot use the exposed port function.

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" amazing_wiles
172.21.111.251

ed2248e00f74 microsoft/iis "C:\ServiceMonitor..." 12 minutes ago Up 12 minutes 0.0.0.0:12345->80/tcp amazing_wiles

@londoncalling

This comment has been minimized.

Copy link

londoncalling commented Dec 27, 2017

@joshijimit

This comment has been minimized.

Copy link

joshijimit commented Dec 27, 2017

@kimtso , As per the comment from @kallie-b and @nickweavers it seems you should be able to access iis through localhost:80 (i.e just localhost) if you are using the latest build. If you can't, try to run "docker-machine ip" command in your docker terminal and use that ip to access your IIS.

image

@nickweavers

This comment has been minimized.

Copy link

nickweavers commented Dec 27, 2017

@joshijimit, where does the docker-machine command come from? It doesn't appear to be part of the docker client. My docker clients is

17.09.1-ce, build 19e2cf6

Am I missing something?

nickw@DESKTOP-OREBB4V:~
$docker --version
Docker version 17.09.1-ce, build 19e2cf6
nickw@DESKTOP-OREBB4V:~
$docker-machine ip
docker-machine: command not found
nickw@DESKTOP-OREBB4V:~
$
@praneetloke

This comment has been minimized.

Copy link

praneetloke commented Mar 11, 2018

@cryocaustik the difference is because --expose only exposes the port. It might be equivalent to the EXPOSE instruction in your Dockerfile. The difference being you are exposing from your container a port at runtime. -p actually publishes your port to the host. You can read about them here.

@selvex

This comment has been minimized.

Copy link

selvex commented Apr 15, 2018

Using the docker-machine ip:port was the solution for me.

@unlikezy

This comment has been minimized.

Copy link

unlikezy commented May 4, 2018

@szydan
problem solved by following your step.
but except that we don't need to restart virtualbox finally.

@carehart

This comment has been minimized.

Copy link

carehart commented May 10, 2018

If I'm understanding the OP right, this problem is fixed (for Windows 10, at least) with the April 2018 Windows update. More at this MS Technet post (where you should look for "Localhost/loopback support for accessing containers". Sorry no anchor to offer.) Or for a more substantive discussion, from when it was first offered as an Insider's build, see this Nov 2017 technet post

@cmeeren

This comment has been minimized.

Copy link

cmeeren commented Jun 7, 2018

Is this the same as #458? I experience this issue even after the April 2018 update.

@daschott

This comment has been minimized.

Copy link

daschott commented Jun 27, 2018

Hi @cmeeren @carehart , speaking here on behalf of the Windows Core networking team.

You are correct that this feature was released in Windows Server, version 1803. Unfortunately, it turned out that a bug was introduced which broke functionality for a subset of users. To be more specific: if you had a network adapter which is connected (and has a 169.254.x.y IP address) localhost stopped working.

The workaround was to disable any remaining adapters which have a 169.254.x.y IP address assigned.

Meanwhile, we fixed this issue with Windows Insider build 17692 and above. We are still working on all the checkmarks that are needed to be able to propagate this fix to Windows April 2018 Update and Windows Server, version 1803. I will post back here if a KB is released.

@cmeeren

This comment has been minimized.

Copy link

cmeeren commented Jun 28, 2018

I can confirm it works for me now, and that I have no network adapters with IP 169.254.x.y. I might have had such an adapter when I reported the problem.

@pbering

This comment has been minimized.

Copy link

pbering commented Jun 28, 2018

@daschott FYI: I did not have this problem and localhost was working fine, but I was trying to resolve another issue and then I did:

  1. Uninstalled Docker for Windows, Hyper-V and Containers feature
  2. Rebooted.
  3. Removed all network adapters so I only had one for my wired connection
  4. Rebooted.
  5. Installed Docker for Windows, Hyper-V and Containers feature once again.

And now localhost/127.0.0.1 is not working at all for Windows containers, containers works fine using their assigned IP's . I don't have any adapters with the 169.254.x.y range....

So something else is also messing with this.

@hosaka

This comment has been minimized.

Copy link

hosaka commented Jul 4, 2018

17704 insider build here, container with just plain ubuntu and python running a flask application on port 5000, docker ps shows 0.0.0.0:8080->5000, pointing to localhost:8080 yields nothing

@daschott

This comment has been minimized.

Copy link

daschott commented Jul 5, 2018

Thx for following up, we will continue to try and reproduce this issue. To expedite the process,
@hosaka which docker version are you using? Is it only Linux containers or also Windows containers that do not work?
@pbering Which Windows Insider build/docker version are you using?

Also, I can confirm that we will release an update with the fix in Windows 10 April 2018 and Windows Server, version 1803. ETA is in July 2018.

@pbering

This comment has been minimized.

Copy link

pbering commented Jul 5, 2018

@daschott, Windows 10 Enterprise 1803 build 17134.137 (not insider) and Docker is 18.03.1-ce-win65 (17513) (stable)

@hosaka

This comment has been minimized.

Copy link

hosaka commented Jul 6, 2018

@daschott I haven't tried with Windows containers, only Linux so far. Windows Insider Preview Build 17704.rs_prerelease.180623-1611:

PS C:\wa\ix\ix-api-service> docker --version
Docker version 18.03.1-ce, build 9ee9f40
PS C:\wa\ix\ix-api-service> docker build -t "ix-api-service" .
...
PS C:\wa\ix\ix-api-service> docker run -p 5000:5000 ix-api-service
 * Serving Flask app "app" (lazy loading)
...
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

From another PS:

PS C:\> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
11c81bdf5a93        ix-api-service      "/bin/sh -c 'python3…"   5 minutes ago       Up 5 minutes        0.0.0.0:5000->5000/tcp   confident_shtern
PS C:\> Invoke-RestMethod -Uri http://127.0.0.1:5000
Invoke-RestMethod : The underlying connection was closed: The connection was closed unexpectedly.

Running the Flask app without the container obv works:

PS C:\> Invoke-RestMethod -Uri http://127.0.0.1:5000

html
----
html

I'm not gonna dump the ipconfig /all here, but there are no ip addresses with the 169.254.x.y range.

@daschott

This comment has been minimized.

Copy link

daschott commented Jul 30, 2018

@pbering
Thanks for patiently waiting. We backported the container localhost/loopback access fix for Windows April 2018 Update (Windows 10 version 1803) through KB4340917, available now.

To validate this fix, you can use docker run -p 8080:80 microsoft/iis command. Once the container is running, you should be able to use loopback and access the container using http://localhost:8080 or http://127.0.0.1:8080.

@hosaka Apologies for the delay here -- can you try the above steps and see if they work for you? Otherwise, does your flask app expect any specific ports? Can you access it by http://:5000?

@panmanphil

This comment has been minimized.

Copy link
Author

panmanphil commented Jul 30, 2018

I can confirm it works on the localhost address/port. Also that it is no longer accessible on the ip address shown by docker inspect. Not sure if that is by design or not, but I found it surprising at least.

@daschott

This comment has been minimized.

Copy link

daschott commented Jul 30, 2018

@panmanphil Are you using http://:?
In my example linked above, I used container port 80. I think in your initial example you used port 8000.
Can you confirm what command you used to launch container and test the connectivity?

@panmanphil

This comment has been minimized.

Copy link
Author

panmanphil commented Jul 30, 2018

Yeah, false alarm! When accessing the container via it's network address, I needed to use the container port 80 not the host port 5000:

 tasty-app           "dotnet app/tasty-si…"   31 seconds ago      Up 6 seconds        0.0.0.0:5000->80/tcp   tasty

docker  inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' tasty
192.168.228.207

invoke-webrequest http://192.168.228.207:80/api/chow -usebasicparsing


StatusCode        : 200
StatusDescription : OK
Content           : ["sammy","yogurt","burger","burger","burger","not-bacon"]
RawContent        : HTTP/1.1 200 OK

invoke-webrequest http://127.0.0.1:5000/api/chow -usebasicparsing

StatusCode        : 200
StatusDescription : OK
@SamuelBradley

This comment has been minimized.

Copy link

SamuelBradley commented Aug 15, 2018

I found a solution to the problem I was having Accessing a jenkins container via http://hostname:8080 from another network computer. My host is a windows 10 box running docker for windows (linux containers).

I had to manually open the port in the firewall settings. Worked immediately after I added the rule.
See:
https://www.tomshardware.com/news/how-to-open-firewall-ports-in-windows-10,36451.html

@antonioftamura

This comment has been minimized.

Copy link

antonioftamura commented Nov 17, 2018

I found this solution and worked great:

route add 172.17.0.0 mask 255.255.0.0 10.0.75.2 -p

Just need to open powershell or CMD with Administration Permission and execute.

@JoeyOverby

This comment has been minimized.

Copy link

JoeyOverby commented Nov 18, 2018

After trying a ton of these ideas, I just used this address to connect to the docker container!

http://host.docker.internal:8080

Note: This worked for me on Windows 10 Pro, running linux containers through WSL.

@daschott

This comment has been minimized.

Copy link

daschott commented Nov 19, 2018

@SamuelBradley Can you confirm that this workaround is no longer needed in Windows Server 2019? There is a fix there for this known port-mapping issue.

@SamuelBradley

This comment has been minimized.

Copy link

SamuelBradley commented Nov 20, 2018

@daschott sorry can't confirm for windows server as im using windows 10 though adding firewall rules isnt really a workaround its just a manuel step. In my experience Windows server would be more pedantic about firewall rules than a consumer edition like Windows 10.

@katlimruiz

This comment has been minimized.

Copy link

katlimruiz commented Dec 18, 2018

I'm not sure if this is entirely true but this seems to have worked for me:

  1. I'm using Docker for Windows 10 Pro, but running a linux node container
    2, When I do a hostname -i from inside the container it gives me 172.17.0.2, so when I try http://172.17.0.2:3010, IT DIDNT WORK!
  2. After some hours, I found this thread, and it said something along "do ipconfig and try all the IPs". So I did and it worked. When I entered http://10.0.75.1:3010 it works!.
  3. I'm not sure if it is related but it is likely. Docker subnet is 10.0.75.0. Which tells me that each container will have its IP address based on that subnet (+1).

Hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment