https://github.com/docker/docker/issues/1143 is closed but not resolved.
I do not know how to reopen it, so I created this issue.
Summary: I need a reliable way to access a service running on the host from a docker container.
Therefore I need the IP address of the host that is reachable from the container
Scenario: I have a configuration DB that runs on the host and the docker container should get its configuration (and perhaps even some updates) from the DB.
Several ways:
ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'
172.17.42.1
$ ip route get 1.1.1.1 | grep -Eo 'via \S+' | awk '{ print $2 }'
172.17.42.1
Add a static address to your host's lo interface, such as 169.254.0.1/32, and talk to that from inside the container.
@phemmer do you know how _reliable_ these mechanisms are? I.e., do they simply work for now, or is it a "supported API"? In #1143 at least the first to variants were considered "workarounds".
:+1: any convenient official api is much needed.
This is my opinion as someone new to docker, so take it for what its worth.
alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
docker run -e HOSTIP=$(hostip) myimage
Dockerfile
FROM centos:centos6
ENV HOSTIP UNKNOWN
CMD /bin/echo $HOSTIP
Command line
```
docker build -t myimage .
docker run -e HOSTIP=$(hostip) myimage
192.168.1.201
```
While this is a *nix specific workaround, and direct support from within docker would certainly be nice, I don't think this will suddenly become unusable with a future docker release. I think people are safe to use this for the time being. Perhaps someone more official than me could confirm or deny these thoughts?
Holy cow! this looks pretty neat.
Another possibility I forgot to mention. In addition to adding a static IP to the loopback interface, you can also just hard set the IP docker uses for the docker0 bridge. docker --bip=172.17.42.1/16, and then use that address in the container.
I also wrote http://github.com/erikh/tfip to make parsing of these values simpler, fwiw.
Going to leave this open because we really should address this.
rather than setting an Environment variable, you can also do docker run --add-host=docker:$(hostip) to add it to the container's /etc/hosts file.
and there's some docs, as it gives an example of using --add-hosts :)
Cool, thanks for adding @SvenDowideit
@SvenDowideit docker run --add-host=docker:$(hostip) will set the host docker to the gateway of the gateway of the host, not to the ip that can be used to reach the host from the container.
Many suggestions have been brought to this issue, and show that no code change is required to address the use case: I'm closing this.
@icecrime That there is no code change needed, does not entail that the issue is solved. If you look at https://github.com/docker/docker/issues/1143, you can see that there still is quite some interest in an officially supported solution. I.e. the issue could be 'fixed' by having a solution documented. To me sll these solutions sound like workarounds that may or may not work in the future.
Please reopen.
Since I originally opened this issue because https://github.com/docker/docker/issues/1143 had been closed, I will refrain from creating the next issue.
Issue: I need a reliable way to access a service running on the host from a docker container
Answer: http://docs.docker.com/reference/commandline/cli/#adding-entries-to-a-container-hosts-file
Note: Sometimes you need to connect to the Docker host, which means getting the IP address of the host. You can use the following shell commands to simplify this process:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run --add-host=docker:$(hostip) --rm -it debian
This is an officially supported solution that will work in the future. Sorry, I don't see what's missing there.
@icecrime thank you!
_that_was missing: a link to the documentation
How can you do this with docker-compose and docker-swarm?
Link to the docs has changed from https://github.com/docker/docker/issues/8395#issuecomment-77088044. This is the new one.
That link seems outdated already as well. I can only find those commands in these old 1.3 docs: https://docs.docker.com/v1.3/reference/commandline/cli/
Here is the correct link: https://docs.docker.com/engine/reference/run/#managing-etc-hosts
Note: Sometimes you need to connect to the Docker host, which means getting the IP address of the host. You can use the following shell commands to simplify this process:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run --add-host=docker:$(hostip) --rm -it debianThis is an officially supported solution that will work in the future. Sorry, I don't see what's missing there.
Except this solutions fails.
The hostip command returns the correct IP inside the container, however in the example it's run in the host, and so returns the host's gateway, which is not necessarily the same as the host ip from within the container.
In my case this happens:
root@<host># docker run --add-host=docker:$(hostip) --rm -it debian
root@<container># cat /etc/hosts
...
130.0.10.1 docker # <--- Docker host's gateway, cannot be used to connect to host
...
root@<container># ip route show 0.0.0.0/0
default via 172.17.0.1 dev eth0 # <--- Docker host IP
A correct solution to this problem imo should work inside a container that has no executables. I shouldn't have to run some hacky bash command from within the container to get the IP
@Frankyh
A correct solution to this problem imo should work inside a container that has no executables. I shouldn't have to run some hacky bash command from within the container to get the IP
I agree.
The snippet provided doesn't suggest running the commands from "within the container" to get the IP, though you could do that if you want/need to, using the same tools...
The solution quoted above
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run --add-host=docker:$(hostip) --rm -it debian
is close, but also _wrong_ as you've noticed.
It incorrectly returns the docker host's default route next hop (aka gateway IP), instead of the local machine's IP. I don't know what the author of it was thinking. It's totally wrong for the question being asked.
The question everyone is asking is "what IP address do I connect to, inside a container, to reach services on the docker host?"
The answer depends on your --net setting at runtime.
With --net=bridge, it's usually the docker0 IP (for services that listen on 0.0.0.0 or tightly bind to all interfaces.)
With --net=host, it's your eth0 IP (or whatever your non loopback interface is that services bind to, again depending on the behavior of the service listening).
On the docker host... these return the correct values....
export DOCKER0_INTERFACE_IP=$(ip route list dev docker0 | awk 'NR==1 {print $NF}')
export DEFAULT_ROUTE_INTERFACE_IP=$(ip route list | awk '/default/ {print $3; exit}')
Plumbing them to --add-host=dockerhost:... depending on your --net setting is up to you.
Issue: I need a reliable way to access a service running on the host from a docker container
Answer: http://docs.docker.com/reference/commandline/cli/#adding-entries-to-a-container-hosts-fileNote: Sometimes you need to connect to the Docker host, which means getting the IP address of the host. You can use the following shell commands to simplify this process:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
$ docker run --add-host=docker:$(hostip) --rm -it debian
This is an officially supported solution that will work in the future. Sorry, I don't see what's missing there.
Although I really appreciate this answer, it does not work in OS X. And I can't imagine it working in windows. A _docker coded_ solution would be much appreciated.
For those of you on os x, I was able to do this by creating an alias as mentioned in the 2nd comment of this issue:
Add a static address to your host's lo interface, such as 169.254.0.1/32, and talk to that from inside the container.
host $ sudo ifconfig lo0 alias 192.168.100.102
container $ curl 192.168.100.102:8000 -> success
What's about the dockerhost entry proposition found in https://github.com/docker/docker/issues/23177?
The solutions proposed here are useful (albeit very hackish) workarounds when you deal with Dockerfiles only, but when you handle them via docker-compose it's a whole different story because then you can't plumb things like you'd do in a docker build --add-host ... command.
The built-in addition of a dockerhost entry would somehow simplify things I guess.
So @icecrime I can't see how this issue can be considered solved, for now. At least, when you're using docker-compose to manage your containers. Or, I may have missed something in the docs.
@reallistic Is it possible to explain why previous way did not work? I tried as well and same result.
@icecrime Can you also give a clue why it does not work?
@cemo Mac OS X does not provide the same ip binary interface as other linux flavors. There is perhaps a way to do it with that _method_ just not that _command_.
I have a problem and I wanted to know if this works - instead of docker0 ip address to communicate to docker host, can I use the LAN/public IP of the docker host to talk from the container to host ?
Most helpful comment
Except this solutions fails.
The hostip command returns the correct IP inside the container, however in the example it's run in the host, and so returns the host's gateway, which is not necessarily the same as the host ip from within the container.
In my case this happens:
A correct solution to this problem imo should work inside a container that has no executables. I shouldn't have to run some hacky bash command from within the container to get the IP