Understanding the 'docker.for.mac.localhost' behavior

I’m trying to understand the behavior of the docker.for.mac.localhost pseudo-dns entry in Docker for Mac as part of deploying OpenWhisk with a local CouchDB instance on my Mac. (Caveat – yes, I could try to run CouchDB in the docker-verse, but that really isn’t a good long-term plan.)

So, here’s the behavior I see inside a stock ubuntu:debian image:

root@2d798bc8ec14:/# curl http://docker.for.mac.localhost:5984/
{"couchdb":"Welcome","uuid":"002908a902322b74aeef1bce3e51a465","version":"1.7.1","vendor":{"name":"Homebrew","version":"1.7.1"}}
root@2d798bc8ec14:/# dig docker.for.mac.localhost

; <<>> DiG 9.10.3-P4-Ubuntu <<>> docker.for.mac.localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 204
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;docker.for.mac.localhost.	IN	A

;; ANSWER SECTION:
docker.for.mac.localhost. 0	IN	A	172.17.0.1

;; Query time: 0 msec
;; SERVER: 192.168.65.1#53(192.168.65.1)
;; WHEN: Fri Nov 24 14:22:55 UTC 2017
;; MSG SIZE  rcvd: 58

root@2d798bc8ec14:/# curl http://192.168.65.1:5984/
{"couchdb":"Welcome","uuid":"002908a902322b74aeef1bce3e51a465","version":"1.7.1","vendor":{"name":"Homebrew","version":"1.7.1"}}
root@2d798bc8ec14:/# curl http://172.17.0.1:5984/
curl: (7) Failed to connect to 172.17.0.1 port 5984: Connection refused

My response, of course, is “Huh.” DNS resolves to a 172.17.0.1 address, which I expected, but that address can’t be connected explicitly. Meanwhile the underlying address from which it was served (192.168.65.1) works like a charm. So why doesn’t docker.for.mac.localhost just resolve to that address?

I’m sure there’s a good reason, but meanwhile I have a Java application that’s not connecting because (I suspect) it resolves the address to 172.17.0.1 and then explicitly uses the numeric IP for connection. Any illumination on underlying implementation and rationale would be greatly appreciated, because I think docker.for.mac.localhost is a great idea, but without understanding how it works, I’m guaranteed to use it incorrectly and create pain.

Not being a docker developer I can just speculate: 192.168.65.1 is an address magically mapped to 127.0.0.1 in the host network namespace, while 172.17.0.1 is the gateway address in the bridge network. The latter is used by default for forwarding all outbound traffic to other computers until you start to reconfigure your container’s routing table. So actually they belong to two different networks not reachable from each other.

In the meanwhile the DNS server seems to be fixed. With 17.09.1-ce-mac42, I get:

/ # drill docker.for.mac.localhost
;; QUESTION SECTION:
;; docker.for.mac.localhost.	IN	A

;; ANSWER SECTION:
docker.for.mac.localhost.	0	IN	A	192.168.65.1

;; SERVER: 192.168.65.1

One more hypothesis: the setting “Docker subnet” on the “Advanced” preferences tab seems to have magic influence on docker.for.mac.localhost resolution. It properly works when you enter 192.168.65.0 there.

To anyone else ending up here in a confused google search:
docker.for.mac.localhost no longer works, at least Docker for Mac Edge Version 18.03.0-ce-rc4-mac57 (23360). Use docker.for.mac.host.internal instead!

3 Likes

Okay docker.for.mac.host.internal is deprecated, they switched to host.docker.internal.

DNS name host.docker.internal should be used for host resolution from containers. Older aliases (still valid) are deprecated in favor of this one. (See draft-west-let-localhost-be-localhost-06).

2 Likes