TL, DR
Docker is a great platform for development and deployment of modern applications. Sometimes you need your Docker container to access some resource published on the host. This guide explains how to access host resources from a Docker container in Linux, Windows, and MacOS.
Docker containers
In today’s cloud environment Docker is one of the foundational technologies. You can build micro services with a full control on their networking and isolation between them, and deploy them in the cloud or on a local machine.
However, sometimes you may have the need for some of your containers to access resources published on the host. It may be a database that you also need to access from outside the host (for example a MongoDB instance that you also want to access with Compass on you laptop), or any other resource that is available on a host port.
Docker provides you a way to do so, but it’s not immediate and may vary depending on your host OS. Here a quick guide on what to do and what doesn’t work instead.
localhost is not your real host
First of all, let’s say what does not work. Calling “localhost
” (or 127.0.0.1 using its IP address) from your container will not yield the results you want. In fact, your container thinks of “localhost
” as itself.
Therefore, if you try to reach port 27017 on “localhost
” from your container, it will attempt accessing that port on itself (usually with poor results). Hence we need to pursue a different route.
Sharing everything is not great
There is an approach tat works, but it’s not suggested: sharing all network resources between your container and the host. You can do so when you launch the container from the terminal in this way:
docker run --rm -d --network host --name my_nginx nginx
The command above will launch a nginx instance called my_nginx (–name flag) in the background (-d flag) that will clean up after it terminates it’s process (–rm flag). What it matters to us is that it will share the network stack with the host (–network flag with host value). Therefore you can access the container ports/services from the host, and the container will be able to access the host ports as well.
However, the host networking driver only works on Linux hosts, and it is not supported on Docker Desktop for Mac or Windows. Moreover, you may run into conflicts if multiple containers want to communicate on the same port. Hence we would be better off with some different solution.
Making it work on Windows and MacOS
Luckily Docker developers provided some way for enabling a container to access resources on the host machine. One of them is specifically aimed to Docker for Mac and Docker for Windows users.
In those two cases, you can refer to the host machine network using the keyword host.docker.internal
. Therefore, if you want to access port 27107 on the host, the code inside your container need to point to host.docker.internal:27017
.
Making it work in Linux
In Linux, starting from Docker Engine v20.10 you can do a trick to use the same magic keyword described above (no, it won’t work just out of the box as things are now).
The trick is to map this magic keyword (or any other keyword if you don’t link host.docker.internal
) to the host gateway for the Docker network your container is connected to. In order to do so, you can use this flag when you run a container from the command line:
--add-host=host.docker.internal:host-gateway
In a Docker Compose file, you can achieve the same result adding the following option to your container/service:
extra_hosts:
- "host.docker.internal:host-gateway"
For Docker Engine versions 20.04 until 20.10, users report that the host-gateway
denomination does not work, and you need to specify the IP address for the gateway of the Docker network to which your container is connected. The gateway for the default Docker network is 172.17.0.1 , but this may change if you connect your container to a different bridge network.
Related links
- Docker Compose file v2 Extra Host option link
- Docker Desktop for Windows Networking documentation link
Do you like our content? Check more of our posts in our blog!