Home > Back-end >  Access host database from service located in a docker container
Access host database from service located in a docker container

Time:05-07

If I have a Postgres database running on the host machine (os: Linux), and some service running in a container of docker-compose. How would I access the database from service in a container? How .yaml file of the service in docker-compose should look like?

CodePudding user response:

Using recent (20.10 or later) versions of Docker on Linux, you can configure a host alias using the host-gateway target, like this:

docker run -it --rm --add-host host.docker.internal:host-gateway alpine

Or in your docker-compose.yaml:

version: "3"

services:
  myservice:
    image: myimage
    extra_hosts:
      - host.docker.internal:host-gateway

With this configuration, you can refer to your hostas host.docker.internal (support for this was added in https://github.com/moby/moby/pull/40007). Support for the host.docker.internal alias has been available under MacOS and Windows for a while (where the network configuration made it more of a necessity).

For example:

host$ docker run -it --rm --add-host host.docker.internal:host-gateway alpine sh
/ # ping -c1 host.docker.internal
PING host.docker.internal (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.049 ms

--- host.docker.internal ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.049/0.049/0.049 ms
/ #

You're not required to use the name host.docker.internal; you could just as easily run:

host$ docker run -it --rm --add-host bobs.yer.uncle:host-gateway alpine sh
/ # ping -c1 bobs.yer.uncle
PING bobs.yer.uncle (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.116 ms

--- bobs.yer.uncle ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.116/0.116/0.116 ms
/ #

But the name host.docker.internal shows up various bits of documentation so it makes a good choice.


Prior to Docker 20.10, I would have said:

On Linux, the host can be reached at any of it's non-localhost addresses. A convenient target is the address of the Docker bridge to which your container is connected (docker0 when using the default network, or the one created dynamically for other Docker networks).

So if your system has an interface configuration like this:

[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:aa:fa:77 brd ff:ff:ff:ff:ff:ff
    altname enp1s0
    inet 192.168.123.106/24 brd 192.168.123.255 scope global dynamic noprefixroute eth0
       valid_lft 2648sec preferred_lft 2648sec
    inet6 fe80::5054:ff:feaa:fa77/64 scope link
       valid_lft forever preferred_lft forever
6: docker_gwbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:3d:cf:c5:af brd ff:ff:ff:ff:ff:ff
    inet 172.23.0.1/16 brd 172.23.255.255 scope global docker_gwbridge
       valid_lft forever preferred_lft forever
    inet6 fe80::42:3dff:fecf:c5af/64 scope link
       valid_lft forever preferred_lft forever
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:51:75:28:24 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:51ff:fe75:2824/64 scope link
       valid_lft forever preferred_lft forever
[...]

You could use either 192.168.123.106, 172.23.0.1, or 172.17.0.1 as the address of your host.

From inside a container, you can get the address of the associated bridge by looking up the default gateway:

$ ip route | awk '$1 == "default" {print $3}'
172.17.0.1

Otherwise, just pick a host address and use it. Note that if you're running with a restrictive firewall configuration you may need to open the necessary ports to permit the access.


NB:

  • You cannot assume the address of the docker0 bridge will be 172.17.0.1: depending on your local network configuration, Docker may choose a different network range for that bridge (so, just check first).

  • If you are running with a restrictive firewall configuration, you may need to open up the necessary ports in order for containers to access services on your host.

CodePudding user response:

On Linux, the host can be reached at 172.17.0.1.

You usually don't change anything in your docker-compose file. You change the settings in your program where you tell it the address of the database server.

  • Related