skip to Main Content

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?

2

Answers


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

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search