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

how to connect to Docker host from container #8395

Closed
kontrafiktion opened this issue Oct 4, 2014 · 26 comments
Closed

how to connect to Docker host from container #8395

kontrafiktion opened this issue Oct 4, 2014 · 26 comments

Comments

@kontrafiktion
Copy link

#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.

@phemmer
Copy link
Contributor

phemmer commented Oct 4, 2014

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.

@kontrafiktion
Copy link
Author

@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".

@gaastonsr
Copy link

👍 any convenient official api is much needed.

@lwoodson
Copy link

lwoodson commented Oct 6, 2014

This is my opinion as someone new to docker, so take it for what its worth.

  1. The -e flags for docker run are the means to pass environment variables from the host to a container. This is a basic need that I cannot fathom would go away or change drastically.
  2. The suggested command to find the host's IP address uses the /sbin/ip, which should be pretty widespread among platforms and would not be going anywhere either, providing you are on a *nix variant to begin with. If you are on another platform, you'll need to find another stable way to get this information.
  3. Its easy enough to create an alias for that command
alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print \$2 }'"
  1. With an easy to use alias, its easy to pass the host IP to the container via environment variables
docker run -e HOSTIP=$(hostip) myimage
  1. Then within your container, you can use that env variable as you see fit. Here is an example:

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?

@gaastonsr
Copy link

Holy cow! this looks pretty neat.

@phemmer
Copy link
Contributor

phemmer commented Oct 7, 2014

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.

@erikh erikh self-assigned this Oct 14, 2014
@erikh
Copy link
Contributor

erikh commented Oct 14, 2014

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.

@SvenDowideit
Copy link
Contributor

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.

@SvenDowideit
Copy link
Contributor

and there's some docs, as it gives an example of using --add-hosts :)

@lwoodson
Copy link

Cool, thanks for adding @SvenDowideit

@retog
Copy link

retog commented Jan 14, 2015

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

@icecrime
Copy link
Contributor

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.

@kontrafiktion
Copy link
Author

@icecrime That there is no code change needed, does not entail that the issue is solved. If you look at #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 #1143 had been closed, I will refrain from creating the next issue.

@icecrime
Copy link
Contributor

icecrime commented Mar 4, 2015

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.

@kontrafiktion
Copy link
Author

@icecrime thank you!
_that_was missing: a link to the documentation

@gtmtech
Copy link

gtmtech commented Jul 2, 2015

How can you do this with docker-compose and docker-swarm?

@theodorosploumis
Copy link

Link to the docs has changed from #8395 (comment). This is the new one.

http://docs.docker.com/reference/run/#network-settings

@chris-martin
Copy link

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/

@mfaure
Copy link

mfaure commented Mar 12, 2016

Here is the correct link: https://docs.docker.com/engine/reference/run/#managing-etc-hosts

@frankh
Copy link

frankh commented Mar 24, 2016

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.

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

@tamsky
Copy link
Contributor

tamsky commented Apr 19, 2016

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

@reallistic
Copy link

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.

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

@JivanRoquet
Copy link

JivanRoquet commented Jun 29, 2016

What's about the dockerhost entry proposition found in #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.

@cemo
Copy link

cemo commented Jul 13, 2016

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

@reallistic
Copy link

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

@sburnwal
Copy link

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 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests