moby / moby

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
https://mobyproject.org/
Apache License 2.0
68.86k stars 18.67k forks source link

port exposure on windows = ? #15740

Closed altsheets closed 9 years ago

altsheets commented 9 years ago

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 commented 9 years ago

$ 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 commented 9 years ago

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.

altsheets commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

@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;

Hope this helps!

polkhovsky commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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

dnemoga commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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

mathiasconradt commented 8 years ago

@thaJeztah Sure, created it at https://github.com/docker/docker/issues/21558

andyneff commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

@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:

Edit: Editing the hosts file worked just as well.

jjlauer commented 7 years ago

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 commented 7 years ago

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

gyde commented 6 years ago

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 commented 6 years ago

@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 :-(