docker/for-mac

Unable to connect to the Docker Container from the host browser on MacOS

V1Reddy opened this issue · 45 comments

Expected behavior

Able to connect to the docker container using the container's IP address

Actual behavior

Receiving connection timed out error while trying to connect to the already running Container

Information

I am not able to connect to the Container that is being hosted at 172.0.0.2:8090 from the host browser on Mac (OS X El Capitan)

Steps to reproduce the behavior

  1. docker run -p 8090:8090 -i owasp/zap2docker-stable zap.sh -daemon -port 8090 -host 0.0.0.0 -config api.disablekey=true
  2. docker ps
  3. docker inspect | grep "IPAddress"
  4. Type the url http://172.0.0.2:8090/UI in the Firefox (or chrome) browser and ultimately the connection gets timed out.

Is this is a known issue in Mac for Docker containers? Am I missing any configuration or settings to allow the traffic from the host browser to the Docker containers?

Any suggestions will be much appreciated.

Thanks.

You cannot access container IPs directly on mac. You need to use localhost with port forwarding

In your example you should be able to connect by running http://localhost:8090

See https://docs.docker.com/docker-for-mac/networking/#known-limitations-use-cases-and-workarounds

Unfortunately, the docker app I am trying to run doesn't let the localhost connect to it's API. And so, I have to find a way to connect to it's API through a specific IP address.

I will checkout the link you provided and see if there are any workarounds.

Thanks much!

djs55 commented

Thanks for your report.

At the moment it's not easy in Docker for Mac to connect to the internal IP addresses used by containers, because they're exposed in a tiny VM rather than on the host. Ideally specific ports should be published with docker run -p which sets up a tunnel from the Mac to the VM. However if that doesn't work or is impractical for your use-case, then perhaps you could try this experimental build which contains a SOCKS server:

https://download-stage.docker.com/mac/bysha1/52ea5bcc410a8b62f03f09aa04ad4b7ffb9eed0c/Docker.dmg

It reports its version as

Version 18.03.0-ce-rc2-mac56 (23206)
Channel: pr
52ea5bcc41

To enable the proxy first shutdown the app, then enable the experimental SOCKS
server on port 8888: (this requires the jq tool available from homebrew)

cd ~/Library/Group\ Containers/group.com.docker/
mv settings.json settings.json.backup
cat settings.json.backup | jq '.["socksProxyPort"]=8888' > settings.json

Restart the app again and, once it's running, go to

Apple System Preferences -> Network -> Advanced -> Proxies

screen shot 2018-03-12 at 16 07 13

and enable "SOCKS Proxy" using "localhost:8888", hit OK and then Apply.

If you open safari and try browsing, the traffic should be routed via Docker for Mac.

If you start an nginx container:

docker run -d --name nginx nginx

Query the internal IP:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx

It should be possible to open http://<IP> in Safari.

Let me know if this is helpful or not!

Thanks @djs55 , I will test and let you know how it goes!

@djs55 When is this feature expected to make it into stable releases? Until then, is there something we can follow to stay up to date with the latest releases that have this SOCKS proxy feature?

BTW, I have tested with the SOCKS proxy feature, and it works well. There is one minor issue; if Docker isn't running, my network doesn't work at all. I've remedied this by using a short proxy.pac file instead of just always pointing to the SOCKS proxy:

function FindProxyForURL(url, host) {
    if (isInNet(host, "172.17.0.0", "255.255.0.0")) {
        return "SOCKS5 127.0.0.1:8888";
    }
    return "DIRECT";
}

Instead of using the SOCKS proxy setting, I used Automatic Proxy Configuration with a file:/// URL pointing to that file. With this, my network will work whether Docker is running or not.

@djs55 Thanks for this. I'm more curious than anything, what made you switch to implementing this using a SOCK proxy instead of the method you were originally doing at #155 (comment)?

djs55 commented

Thanks all for your feedback. I need to discuss this internally with my colleagues.

@derimagia It's really an experiment but I had 3 motivations:

  • we currently use a custom protocol to forward ports exposed with docker run -p and were wondering if we could switch to SOCKS instead to simplify part of the system
  • we had some reliability problems with the vmnet.framework solution in the past. Sometimes it would get into a stuck state and the whole machine would need to be rebooted to fix it (or at least, we never found where the bad state was located). We did report this to Apple and it may have been fixed by now.
  • we were wondering if it would be useful to use SOCKS as a cheap kind of VPN to connect to other places -- maybe if you had a remote cluster and wanted to directly talk to the containers there. Maybe you want to attach yourself to a swarm overlay network (or similar). I'm not sure how useful this is.

Another workaround is to use sudo ifconfig lo0 alias 172.17.0.1 so you can still use the same static IP address (if your Linux-based colleagues or bash scripts insist on using that).

I tried setup instructions from #2670 (comment) with release 18.06.0-ce-rc3-mac68 (26342), but I couldn't access proxy service from OSX using simple telnet connect.
At the beginning I thought the issue is caused by socks service is listening internally 127.0.01, but I tested that theory out with previous experimental build with 18.03.0-ce-rc2-mac56 (23206) and I was able to connect form osx while socks was configure to listen 127.0.0.1.
I only wonder that some routing is missing in the latest build or something else.

djs55 commented

@rreinurm thanks for the info. I've got a prototype fix for the bug and I'll keep you informed of progress.

Thanx @djs55, I was able to enable this experimental feature with release 18.06.0-ce-mac69 (26398)

djs55 commented

@rreinurm thanks for the confirmation (and the reminder!)

The experimental SOCKS proxy should be functional again in both the stable and edge channels. Let me know how it goes and if there are any ways it could be improved further.

I did all steps

docker run -d --name nginx nginx
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
172.17.0.2
and it works on safari/chrome...
but into terminal using curl for example it doesn't work

$ curl -i -v http://172.17.0.2
* Rebuilt URL to: http://172.17.0.2/
*   Trying 172.17.0.2...
* TCP_NODELAY set
* Connection failed
* connect to 172.17.0.2 port 80 failed: Operation timed out
* Failed to connect to 172.17.0.2 port 80: Operation timed out
* Closing connection 0
curl: (7) Failed to connect to 172.17.0.2 port 80: Operation timed out

@sfragata Try http_proxy=socks5://localhost:8888 curl 172.17.0.2 ?

thanks @andrewdotn it worked

A lot of people especially enterprise developers are already using a system proxy. If xhyve came with an ssh server and python, it would be transparent and simple to use sshuttle to route traffic to containers: https://sshuttle.readthedocs.io/en/stable/

Before Docker for Mac was released I used Dinghy (https://github.com/codekitchen/dinghy) which provided an http proxy and DNS. When I switched to Docker for Mac I continued using the proxy and DNS with this bash script https://github.com/aj-may/docker-proxy/

Thanks for the http solution, is there any workaround to ping my docker container IP?

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale comment.
Stale issues will be closed after an additional 30d of inactivity.

Prevent issues from auto-closing with an /lifecycle frozen comment.

If this issue is safe to close now please do so.

Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows.
/lifecycle stale

Is there any workaround to ping my docker container IP?

Something at worked for me was to look at the ifconfig output on my host mac, see which IP corresponded to the docker-swarm host, then use that IP address.

Any way to use the proxy workaround with custom networks? UPD: It does work, I just assumed it wouldn't.

Hi! Everyone, if you use IDEA, i found a easy method for enter container.
1.安装Idea

  1. IDEA 中安装docker plugins 插件

  2. MacOS 系统中安装 Docker for mac

  3. 然后在docker插件中创建连接就好了

image
5 点击已经创建的连接,然后进入到容器
image
6. 因为要进入容器,所以该容器肯定要已经启动了,所以,启动要进入的容器:
image
7。 接下来是重点:

右键已经启动的容器之后,点击exec,然后点击Create,这时候会出现要执行的命令,然后输入: /bin/bash
image

image
然后你就会惊喜的发现,你已经在控制台成功进入到了容器的内部!!!然后就可以为所欲为了
image

Hi! Everyone, if you use IDEA, i found a easy method for enter container.
1.安装Idea

  1. IDEA 中安装docker plugins 插件
  2. MacOS 系统中安装 Docker for mac
  3. 然后在docker插件中创建连接就好了

image
5 点击已经创建的连接,然后进入到容器
image
6. 因为要进入容器,所以该容器肯定要已经启动了,所以,启动要进入的容器:
image
7。 接下来是重点:

右键已经启动的容器之后,点击exec,然后点击Create,这时候会出现要执行的命令,然后输入: /bin/bash
image

image
然后你就会惊喜的发现,你已经在控制台成功进入到了容器的内部!!!然后就可以为所欲为了
image

I appreciate that you are helpful. Not everyone can understand Chinese. I love Chinese,I'm Chinese.It would be better to in English to communicate with others, especially on Github. My little advice.

@djs55 is the socks proxy now built into the official builds? If not, could you provide a current link with it enabled?

This sounds like exactly what I am looking for and I'd love to test it

djs55 commented

@jmunson the code is still there but it's still considered experimental. The instructions above are still accurate -- I tested them on a recent build (2.1.0.0 (36346)).

Let me know if you get it to work and how useful it is (or not). The more positive feedback I get the easier it is to make a case that this should become a supported feature :)

Also if you have other suggestions or ideas for improvement, let me know.

Hi.
The link to that old build give 404. So I assume this feature is now in the current release build, but not exposed in the UI? Do I only need to edit settings.json?

This probably due to my lack of understanding of kubenetes (vs. docker). Docker has IP subnet 192.168.65.0/24 configured, but is see in kubectl get all that my services are on 10.x.x.x IPs.
It appears that the socks proxy does not access the kubenentes subnets?

Also I thought this strange:

localhost:~ root# netstat -n -p tcp | grep 8888
(((nothing)))
localhost:~ root# nc -v localhost 8888
found 0 associations
found 1 connections:
     1:	flags=82<CONNECTED,PREFERRED>
	outif lo0
	src ::1 port 59275
	dst ::1 port 8888
	rank info not available
	TCP aux info available

Connection to localhost port 8888 [tcp/ddi-tcp-1] succeeded!

Maybe I am wrong, this is what I see:

Firefox:

An error occurred during a connection to 10.98.78.18:5601. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG 

curl:

$ export https_proxy=socks5://localhost:8888 
$ curl -k https://10.98.78.18:5601/
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

I appear to have worked through my initial problems and I think this feature should be promoted in the UI! Thank you for adding it to Docker for mac.

For anyone else having trouble following this thread. With a recent version of Docker of Mac, add "socksProxyPort" : 8888, to ~/Library/Group\ Containers/group.com.docker/settings.json (be sure to respect strict json syntax); and restart Docker.

You can use this proxy in your web browser as it will forward "non-docker" traffic (say to google.com) to the internet. However if docker is not running (e.g. to save battery) your browser will no have internet access. You can mitigate this with a proxy manager (e.g. FoxyProxy) or (more technical) with proxy.pac file.

@djs55 I followed your instructions to enable the socks proxy in 2.1.0.0 (36874) stable and it works perfectly to enable me to connect to a port without needing to publish it on the host system. The use case I have is running multiple google cloudsql proxies to connect to different databases in google cloud.

If there was a mechanism to route requests to the containers without needing to setup the proxy, that is the only improvement I can come up with

djs55 commented

@JBodkin-LH thanks for the feedback. Out of interest did you try the proxy.pac improvement suggested by #2670 (comment) ?

I'll make an internal enhancement request ticket and discuss the possibility of making this a first-class feature. My initial worry with it was about the failure mode when the proxy setting is enabled but the app is shutdown-- I think the proxy.pac improvement fixes that nicely.

@djs55 I didn't need to setup PAC file as I was able to configure the socks proxy at the application level rather than the OS level. However from previous experience, using the PAC file would solve the issue when docker is stopped if using OS level configuration

I'm also not using it as an OS setting, but rather in specific apps. In FF I'm using FoxyProxy to only select this proxy for 10.0.0.0/8 which is where my k8s stuff is.

I have a question, does the proxy support DNS names too from the k8s DNS server?

djs55 commented

@ThorbenJ the SOCK proxy endpoint is in a raw container in the VM, not in a k8s pod so it's not using the k8s DNS. It's possible the proxy could be moved. What sort of names are you hoping to resolve?

To be open: I am very new to docker and k8s, that is why I am trying to get hands-on time with both on my laptop, with docker for mac.

I would just like to access services via a name (e.g. the one below) instead of via the IP.

NAMESPACE              NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  
kubernetes-dashboard   service/kubernetes-dashboard        ClusterIP   10.104.65.187    <none>        443/TCP                  9d

I noted this in the same list:

kube-system            service/kube-dns                    ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   14d

.. and thought it could perhaps be used to get names. Its only an optical issue, not a critical one.

I appear to have worked through my initial problems and I think this feature should be promoted in the UI! Thank you for adding it to Docker for mac.

For anyone else having trouble following this thread. With a recent version of Docker of Mac, add "socksProxyPort" : 8888, to ~/Library/Group\ Containers/group.com.docker/settings.json (be sure to respect strict json syntax); and restart Docker.

You can use this proxy in your web browser as it will forward "non-docker" traffic (say to google.com) to the internet. However if docker is not running (e.g. to save battery) your browser will no have internet access. You can mitigate this with a proxy manager (e.g. FoxyProxy) or (more technical) with proxy.pac file.

-- that restarting docker made the trick for me to work, after the proxy settings.
-- mentioning version just in case
image

This is a great approach, @djs55! The only thing I wish it allowed for was DNS resolution as some of our applications use hostnames for internal communication. Only being able to access IP addresses in this way ends up limiting our use of this because, while I can access the initial application via IP, as soon as it redirects me to a different part of the application (i.e. via hostname), it comes up short. Tried to hack something wherein I'd edit the /etc/hosts of the VM, but that's locked down. Any other approaches that might work that come to mind?

I think this article is very useful for everyone having related problems: https://pythonspeed.com/articles/docker-connection-refused/

BTW, I have tested with the SOCKS proxy feature, and it works well. There is one minor issue; if Docker isn't running, my network doesn't work at all. I've remedied this by using a short proxy.pac file instead of just always pointing to the SOCKS proxy:

function FindProxyForURL(url, host) {
    if (isInNet(host, "172.17.0.0", "255.255.0.0")) {
        return "SOCKS5 127.0.0.1:8888";
    }
    return "DIRECT";
}

Instead of using the SOCKS proxy setting, I used Automatic Proxy Configuration with a file:/// URL pointing to that file. With this, my network will work whether Docker is running or not.

Hi Steve, I tried using the proxy.pac file but I can't make it work. Is 172.17.0.0 your container's IP? Can you give me more details please on how to configure it please?

@stevecoug I forgot to tag you in my previous comment.

Can you help me with the proxy.pac file? It's painful to keep on changing proxy settings each time I use docker.

Thanks in advance!

@lucascroxatto I believe that 172.17.0.0 is the default Docker network. I don't actually use this anymore; I'm developing on Linux now, and it just works. Even on Mac, I had stopped using this hack because it was not working correctly with some browsers. It was easier just to figure out a way to do what we needed with port forwarding.

me too. How connect to docker instance of Docker for Mac v19.03.5 on MacOS 10.15.4 ? The docker instance ip is 172.17.0.2 , but I don't found docker0 netcard.

-- this question is solve ,ok.

Closed issues are locked after 30 days of inactivity.
This helps our team focus on active issues.

If you have found a problem that seems similar to this, please open a new issue.

Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows.
/lifecycle locked