DEV Community

Mitz
Mitz

Posted on

Access host from a docker container

This information is as of 2018-03-31 with Docker 18.03.0-ce

I wanted to access host port from a docker container.

For example, an nginx process is running on the host machine with port 8888 open, then I would like to create a container which can curl host:8888.

I know how to discover container-to-container, but don't know how to get host IP address from a container.

Therefore, I wandered the internet.

Precondition

I mainly use Docker for Mac, but sometimes use Linux. So I want my containers to run on both platform.

TL;DR

https://github.com/bufferings/docker-access-host

Host networking mode?

I found Docker has "host networking mode".

https://docs.docker.com/network/host/

With this mode, the container seems to be able access to the host with "127.0.0.1". How easy! I found it!

So I tried it and it works on my Linux machine, but it didn't work on my Mac. Then I found:

https://docs.docker.com/network/network-tutorial-host/#prerequisites

The host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server.

(´・ω・`) ok... let me find another way please.

host.docker.internal?

I found I can resolve host.docker.internal as the host IP address in the container on Docker for Mac. Great! That's what I wanted to know! But... where's Linux version of it...?

(´・ω・`) NotFound...

In addition, I was a little bit confused there're several names:

  • docker.for.mac.localhost <- from 17.06.0 but now deprecated
  • docker.for.mac.host.internal <- from 17.12.0-ce-mac46 but now deprecated
  • host.docker.internal <- from 18.03.0-ce-mac59

https://docs.docker.com/docker-for-mac/release-notes

Finally, my solution is like this.

I created docker-entrypoint.sh :

HOST_DOMAIN="host.docker.internal"
ping -q -c1 $HOST_DOMAIN > /dev/null 2>&1
if [ $? -ne 0 ]; then
  HOST_IP=$(ip route | awk 'NR==1 {print $3}')
  echo -e "$HOST_IP\t$HOST_DOMAIN" >> /etc/hosts
fi

(main entrypoint)
Enter fullscreen mode Exit fullscreen mode

and create Dockerfile call this file as an entry point.

COPY docker-entrypoint.sh /usr/local/bin/

ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
Enter fullscreen mode Exit fullscreen mode

As a result, Docker for Mac do nothing because it has "host.docker.internal" and Linux version add it into hosts file.

(๑•̀ㅂ•́)و✧

The sample code is here:
https://github.com/bufferings/docker-access-host

I hope host.docker.internal will be added for Linux near future.

If you know better solution, please let me know.

Top comments (12)

Collapse
 
qoomon profile image
Bengt Brodersen

I created a docker container for doing exactly that github.com/qoomon/docker-host

you can then simply use container name dns to access host system e.g.

curl http://dockerhost:9200

Collapse
 
axcairns profile image
axcairns

This doesn't work for me on Ubuntu. I cloned your repo and ran the demo and the curl command just hangs. I connected to the container and confirmed the hostname was in the hosts file. I can ping it but curl doesn't work. I had a similar experience with Bengt's container below - pinging works but wget times out.

Collapse
 
axcairns profile image
axcairns

I figured it out. Nothing wrong with your solution. I have my host firewall locked down tight. Port 80 (which is the host service I was trying to access) is locked to only my LAN network. Adding the docker container network shared by all my containers to the firewall rules fixed it.

Collapse
 
gonzalo2683 profile image
Gonzalo Guevara • Edited

Could you show the example of how to allow the connection?

I have the same problem, if I try curl host.docker.internal I get
curl: (7) Failed to connect to host.docker.internal port 80: Connection refused

I am linux

Thread Thread
 
axcairns profile image
axcairns

Been a while so I'm hazy. From memory my docker containers were running on 192.168.0.0/24 while my LAN is on 192.168.1.0/24. I just needed to tell ufw to allow access to that port from 192.168.0.0/24

Thread Thread
 
jamescook profile image
james-cook

I had exactly the same problem.
Confusingly ping was working from the container but e.g. wget and traceroute etc. were not (a good indication of a firewall "problem").

In my set-up the solution was:

ufw allow in to 172.17.0.0/16 proto tcp port 8084

where 172.17.0.1 is the docker0 IP address and 8084 the port on the host machine.

Collapse
 
lucywyman profile image
Lucy Wyman

This is exactly what I needed!! Thank you!

Collapse
 
lon9man profile image
lon9man

how about the opposite?

  1. i have HOST with multiple dockers (1 docker - 1 apache)
  2. i have 1 proxy-apache on HOST with will route request to applicable docker

i want to use in proxy-apache some DNS-names per each docker instead of IPs, which can be dynamic.

so after docker started it should insert own IP into HOST's /etc/hosts.

how to implement this? (very low info in google about such case)

Collapse
 
joshisimt profile image
Gaurav • Edited

Hi @Mitz

I have docker file like this -
FROM openjdk:8
EXPOSE 9999
ADD target/test-0.0.1-SNAPSHOT.jar test-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/test-0.0.1-SNAPSHOT.jar"]

How I can add your entrypoint to this?
Please help.

Thanks

Collapse
 
navono profile image
Darkness

Maybe can use docker-host

Collapse
 
hero9 profile image
Galymzhan Almabek

Thanks author, it worked perfectly

Collapse
 
oriamd profile image
oriamd • Edited

Thank you!
By which hostname should the container call the host? "host.docker.internal"?
can i make it "localhost"?