Skip to content
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

port exposure on windows = ? #15740

Closed
altsheets opened this issue Aug 20, 2015 · 28 comments

Comments

@altsheets
Copy link

commented Aug 20, 2015

port exposure on windows = ?

Windows (7) with Docker (version 1.8.1, build d12ea79):

docker run -d nginx

has no results on the host machine. If I point my browser to

http://localhost/
http://localhost:80

it results in:

This webpage is not available
ERR_CONNECTION_REFUSED

even though I am told it is serving:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS                         NAMES
bc8ae00352f1        nginx               "nginx -g 'daemon off"   10 seconds ago      Up 7 seconds                 80/tcp, 443/tcp               some-nginx

I also tried other variants:

docker run -p 80:80 -d nginx
docker run -p 81:80 -d nginx

they all do work - but have zero effects on Windows.

I also tried the same thing on Linux:

docker run -p 81:80 -d nginx
browser http://myhostip:81/

and it works perfectly. The browser shows:

Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working.

What can I do to create a server that will work platform independent, short term?
What do you have to do to make docker platform independent, long term?

My goal is to wrap my chaincountdown into a docker container, and the docker solution is targeted mainly at Windows users - because on Linux my server is so easy to start anyways.

Docker is great, my first day, and I am already loving it! Just the windows version seems to have quite some issues.

Thanks a lot!

@altsheets

This comment has been minimized.

Copy link
Author

commented Aug 20, 2015

$ docker version
Client:
Version: 1.8.1
API version: 1.20
Go version: go1.4.2
Git commit: d12ea79
Built: Thu Aug 13 02:49:29 UTC 2015
OS/Arch: windows/amd64

Server:
Version: 1.8.1
API version: 1.20
Go version: go1.4.2
Git commit: d12ea79
Built: Thu Aug 13 02:49:29 UTC 2015
OS/Arch: linux/amd64

$ docker info
Containers: 1
Images: 36
Storage Driver: aufs
Root Dir: /mnt/sda1/var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 38
Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.0.9-boot2docker
Operating System: Boot2Docker 1.8.1 (TCL 6.3); master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015
CPUs: 1
Total Memory: 1.956 GiB
Name: default
ID: that seems to be some personalization ID, I object that
Debug mode (server): true
File Descriptors: 15
Goroutines: 27
System Time: 2015-08-20T22:56:31.27926426Z
EventsListeners: 0
Init SHA1:
Init Path: /usr/local/bin/docker
Docker Root Dir: /mnt/sda1/var/lib/docker
Labels:
provider=virtualbox

$ uname -a
MINGW32_NT-6.1 MachineName01 1.0.12(0.46/3/2) 2012-07-05 14:56 i686 unknown

@thaJeztah

This comment has been minimized.

Copy link
Member

commented Aug 20, 2015

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. Feel free to comment here after I've closed this issue.

@thaJeztah thaJeztah closed this Aug 20, 2015

@altsheets

This comment has been minimized.

Copy link
Author

commented Aug 20, 2015

Thanks a lot. That was fast. I am a bit disappointed, that Docker is not platform independent in such a basic question. But what you wrote, actually fixed my problem. Thanks!

Alright then ... I would then have to write this manual for my users (for foobar assuming it were nginx which it is not):

"

if you are on Windows:

docker run -p 80:80 -d nginx
docker-machine ip default   # (they could've named their machine different from 'default !)

then open the browser at:

whatever that last command answered
(in my case 192.168.99.100)

if you are on Linux:

docker run -p 80:80 -d nginx
browser http://localhost

"

Is that correct?

Does anyone has ideas how that could be made more platform independent?

(Perhaps leave this issue open?)

Thanks anyways. Enjoy whatever you do.

:-)

@thaJeztah

This comment has been minimized.

Copy link
Member

commented Aug 20, 2015

Yes, that description is correct. To make things easier, you could have a look at kitematic, which also can be installed with Docker Toolbox, and provides an easy to use interface for this (with clickable links to directly open the website in your browser). Kitematic only runs on Windows and Mac currently.

Unfortunately, we cannot make this behavior more consistent, because the docker-daemon (Docker Engine) cannot run natively on Windows or OS X, so the virtual machine is a requirement to make it possible to run it.

Work is in progress to run Docker Engine natively on Windows Server 2016, but that engine will only run Windows applications, not Linux

@altsheets

This comment has been minimized.

Copy link
Author

commented Aug 21, 2015

That is so sad.

Then I make a bold move - I suggest a new command for Dockerfiles:

GUESTTOHOST

when that command is found in a Dockerfile, it gets completely ignored on a Linux machine;
but on a Windows machine, it causes mapping of the exposed ports of the guest machine to the host machine.

It would be used like this:

EXPOSE 80
EXPOSE 443
GUESTTOHOST

CMD ["nginx"]

and would probably then cause some magic with the Virtualbox-Ethernet-Adapters.

Voilà - platform independence could be -almost- regained.
We users would have to just insert one command into existing Dockerfiles.

What do you think?

@dajester2013

This comment has been minimized.

Copy link

commented Sep 4, 2015

The documented way to do port forwarding does not appear to be working for me on windows:

docker-machine ip <machine>
192.168.99.100

docker run -d nginx
57418e0da25d7f198c76c76fc892b9498448affc3af6498beda4332e13577a52

So then i switch over to my browser, and navigate to http://192.168.99.100, which comes up with ERR_CONNECTION_REFUSED

For good measure, I try:

docker ssh <machine>

# wget localhost
Connecting to localhost (127.0.0.1:80)
wget: can't connect to remote host (127.0.0.1): Connection refused

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
57418e0da25d        nginx               "nginx -g 'daemon off"   4 minutes ago       Up 4 minutes        80/tcp, 443/tcp     loving_colden7
@thaJeztah

This comment has been minimized.

Copy link
Member

commented Sep 4, 2015

@dajester2013 that's because you're not publishing any port of the container, so the containers' ports will only be accessible on the "internal" (inter-container) network. Look at the PORTS column in your last output; you can see that the container "exposes" two ports, but non of the. are published.

Run either;

  • docker run -d -p 80:80 nginx to publish port 80 of the container to port 80 of the host; be sure that port 80 is not yet in use on the host, otherwise this will fail. Repeat the -p flag for each port you want to publish.
  • docker run -d -p 80 nginx to publish port 80 of the container to a randomly picked port on the host (the random port will be visible in the PORTS column of docker ps
  • docker run -d -P nginx (capital -P) to publish all ports that are exposed by the container (80 and 443 in this case) to randomly picked ports on the host.

Hope this helps!

@polkhovsky

This comment has been minimized.

Copy link

commented Mar 16, 2016

I am having the same issue.
docker run -t -d -p 5000:5000 mu-api

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
df1aef61dc1f        mu-api              "dnx -p project.json "   5 seconds ago       Up 4 seconds        0.0.0.0:5000->5000/tcp   berserk_jang
$ docker logs berserk_jang
Hosting environment: Production
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
$ docker-machine ip default
192.168.99.100

Trying to navigate to http://192.168.99.100:5000/api/values results in ERR_CONNECTION_REFUSED

@polkhovsky

This comment has been minimized.

Copy link

commented Mar 16, 2016

I figured it out. Will leave this link with the solution description.
My final version of the Dockerfile line:
ENTRYPOINT ["dnx", "-p", "project.json", "web", "--server.urls", "http://0.0.0.0:5000"]

Hope this helps someone else.

@thaJeztah

This comment has been minimized.

Copy link
Member

commented Mar 16, 2016

@polkhovsky looks like the app in you container is listening on "localhost" only, which is localhost inside the container. Make sure the app is listening on 0.0.0.0, and it'll probably work

@thaJeztah

This comment has been minimized.

Copy link
Member

commented Mar 16, 2016

oh, lol, I see you figured it out, our comments crossed

@dnemoga

This comment has been minimized.

Copy link

commented Mar 23, 2016

Solution for Windows hosts

Here's my Nginx server running on 80 port (for example):

docker run -d -p 80:80 nginx

All you need is just add port forwarding (admin rights required):

netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=80 connectaddress=192.168.99.100 connectport=80

You may change addresses and ports as you need.

@mathiasconradt

This comment has been minimized.

Copy link

commented Mar 27, 2016

@thaJeztah Somewhere above, you mentioned

Work is in progress to run Docker Engine natively on Windows Server 2016, but that engine will only run Windows applications, not Linux

But I am having the problems even on Windows 2016 TP4. I have written a very detailed problem description here:
http://superuser.com/questions/1057223/docker-port-binding-on-windows-server-2016-not-working

(I had followed the instructions https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/inplace_setup ("Setup an existing Virtual Machine or Bare Metal host for Containers") prior to running the docker container, where I use the "bare metal host", no hyper-V)

@thaJeztah

This comment has been minimized.

Copy link
Member

commented Mar 27, 2016

@mathiasconradt can you open a separate issue for that, because that's a different case than docker running in a VM / b2d

@mathiasconradt

This comment has been minimized.

Copy link

commented Mar 27, 2016

@thaJeztah Sure, created it at #21558

@andyneff

This comment has been minimized.

Copy link

commented Jun 10, 2016

Are there any plans to automate and make use of something like @dnemoga suggestion of using the portproxy in windows beta docker? I noticed that SOMEHOW it works in the Mac OSX Beta docker but not Windows Beta Docker. However dnemoga's trick still works.

@janhartigan

This comment has been minimized.

Copy link

commented Jun 11, 2016

For what it's worth, the solution by @dnemoga works quite well. Just some more info to round out the process:

Adding a port proxy (the command used above):

netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=80 connectaddress=192.168.99.100 connectport=80

Showing all existing port proxies:

netsh interface portproxy show v4tov4

Deleting the same port proxy:

netsh interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=80
@sitano

This comment has been minimized.

Copy link

commented Jul 21, 2016

netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=8080 connectaddress={external ip} connectport=80

did not help me on windows 2016 tp 5, virtualbox

@lanjiantm

This comment has been minimized.

Copy link

commented Nov 11, 2016

Open the VirtualBox Manager, choose the docker image (e.g. "default"), click "Settings" on the toolbar, switch to "Network" tab, choose "Adapter 1" tab (the "NAT"), extend "Advanced", click "Port Forwarding", add the port as your need.

Env:
Windows 7, VirtualBox 5.1.8, docker toolbox v1.12.0

@fresheneesz

This comment has been minimized.

Copy link

commented Jan 3, 2017

@thaJeztah Did you close this because either mapping the IP is impossible or undesirable? This was horribly confusing for me. I expected the behavior of docker to be identical on windows, max, and linux. That's part of the point right? Vagrant has no problem mapping localhost into a virtual machine, so why does docker?

If its possible to make this mapping work, can you please reopen this issue?

@friism

This comment has been minimized.

Copy link
Contributor

commented Jan 3, 2017

@fresheneesz With Docker for Windows, Linux containers with mapped ports are available on localhost: https://docs.docker.com/docker-for-windows/#/step-4-explore-the-application-and-run-examples

@fresheneesz

This comment has been minimized.

Copy link

commented Jan 3, 2017

I see, well "Docker for Windows" isn't available on windows home edition (since it doesn't have hypervisor) so I'm forced to use docker-toolbox.

@liamdawson

This comment has been minimized.

Copy link

commented May 3, 2017

I see, well "Docker for Windows" isn't available on windows home edition (since it doesn't have hypervisor) so I'm forced to use docker-toolbox.

Also, I prefer to use Docker Toolbox on Windows regardless, as I often want to run other things in Virtualbox (and I can't feasibly use Virtualbox and Hyper-V without rebooting between).

@omaric

This comment has been minimized.

Copy link

commented Aug 10, 2017

@dnemoga and @janhartigan's solution worked for me after 2.5 days of struggling. Thank you!

Description of problem/solution: I am running Docker Toolbox on Windows 10 Home, because you can't run regular Dockers for Windows on a non-Windows-Pro machine. All components came up, but I couldn't access the website. Entering the IP or domain name in a browser or curl command resulted in a Connection Refused message. Testing with nginx worked just fine, but even after trying literally dozens of other solutions nothing worked.

One specific thing to know about our setup is we have a virtual host name, which let's say is "domayne.moc". All requests on port 80 get forwarded with a 301 redirect to the SSL version of our server, or "https://domayne.moc" (on port 443). Requests to the docker virtual machine IP (192.168.99.100:80, get yours with docker-machine ip [machine-name]) would actually get through to the apache server running in the docker component, but when they were forwarded to https://domayne.moc, they would fail, even after changing the Windows hosts file to forward http(s)://domayne.moc to localhost.

By creating rules in Windows' netsh interface portproxy to forward these domain-port combinations to the docker VM IP, Windows figures out where to send the requests. I'm curious if I should have edited the hosts file to forward to the docker VM instead of "127.0.0.1". I'll test that later.

The specific commands were:

  • netsh interface portproxy add v4tov4 listenaddress=domayne.moc listenport=80 connectaddress=192.168.99.100 connectport=80
  • netsh interface portproxy add v4tov4 listenaddress=domayne.moc listenport=443 connectaddress=192.168.99.100 connectport=443

Edit: Editing the hosts file worked just as well.

@jjlauer

This comment has been minimized.

Copy link

commented Aug 12, 2017

Another alternative method that doesn't require admin right. Make sure virtualbox is in your PATH and you can map a port to localhost via the command-line: VBoxManage.exe controlvm default natpf1 tcp80,tcp,,80,,80

@omaric

This comment has been minimized.

Copy link

commented Aug 14, 2017

Thanks @jjlauer. Note that the VM must be running.

@gyde

This comment has been minimized.

Copy link

commented Jan 11, 2018

A few valuable things I learned when trying to make docker on windows work with localhost is that multiple network devices or other network releated devices might affect the localhost to interface binding.

Had some laptops where disabling "Wifi Switch" in BIOS solved the issue and made docker stable in allowing connections to localhost.

Consider testing by disabling all but your cabled network card in bios to see if any issue stem from these devices.

Weather or not its somethings that has to be fixed within Docker or maybe Windows itself is still unknown, was unable to capture traffic related to the issue on any interfaces, so debugging / stepping within the network core of docker / windows is needed to assign responsibility :)

@dreispt

This comment has been minimized.

Copy link

commented Nov 2, 2018

@thaJeztah Hi, your links to the docs no longer point to useful information. The doc page exists, but I coudn't find there the explanation you are giving here :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.