I’m experimenting with docker networking, and I can’t seem to find a way to accomplish the following:
Start a simple netcat server in the host:
nc -l -p 5555
and then communicate to this server from within a docker container, e.g.
# grab the docker network interface ip
hostip=$(ip route | awk '/docker0/ { print $NF }')
# pass in the docker network interface as a host and try a curl command
docker run --add-host=docker:"${hostip}" --rm -it hiromasaono/curl curl docker:5555
The curl request just hangs and the host netcat server does not receive a request.
If I instead start docker with --net=host
option, it works:
docker run --net=host --rm -it hiromasaono/curl curl 127.0.0.1:5555
and the netcat server receives
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:5555
Accept: */*
How can I communicate to the simple host netcat server from within the docker container without using --net=host
(the default is --net=bridge
)?
(fyi: I'm running docker server/client 1.11.2)
Potentailly Relevant Resources I've Studied in search of an answer:
- Document how to connect to docker host from container (github issue)
- How to connect to Docker host from container (github issue)
- Allow Docker Container to Connect to a Local Postgres DB
- Docker Container Networking Documentation
There are a couple of things you need to look into, in order to solve this problem.
- Netcat must listen on all interfaces (or at least on the interface Docker clients can connect to). Not on localhost.
After you run
netcat -l -p 5555
if in another terminal you run netstat -a -l -n | grep 5555
you should see 0.0.0.0:5555
or *:5555
. If instead you see 127.0.0.1:5555
then it won't work and you need to fix this problem first before looking into Docker.
- Docker must be able to ping the
docker
host and it must not resolve to 127.0.0.1
. Try docker run --net=host --rm -it hiromasaono/curl ping docker
. If you see it's pinging 127.0.0.1
then your configuration is wrong and you need to fix this line: hostip=$(ip route | awk '/docker0/ { print $NF }')
. If it's not 127.0.0.1 but the pings don't succeed then your network setup is wrong or the hostip is wrong.
As far as I understand, based on two comments[1][2], the following unofficial hack seems to be working for me as of today (2016.10.27):
In the Dockerfile
for the app which needs to connect to the Docker host, I added the following lines:
...
# netstat
RUN apt-get update && apt-get install net-tools -y
...
CMD (netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2" dockerhost"}' >> /etc/hosts) && \
...old CMD line...
...
This seems to make the Docker host available to me from within the container as dockerhost
.
Note to future readers: see also https://github.com/docker/docker/issues/23177 — as of writing, this issue is still open, so there's a non-zero chance it may become official at some point in future and supersede any workarounds; though it may also become closed and dismissed as happened to its various predecessors.