18

I have a simple docker-compose set up as follows.

version: "3"
services:
  main:
    image: python:3.5.2
    entrypoint: /usr/bin/yes
    network_mode: bridge

  another:
    image: python:3.5.2
    entrypoint: /usr/bin/yes
    network_mode: bridge

If I run and try to ping the other container, I get the following output.

$ docker-compose up -d
Recreating dockerplayground_main_1 ... 
Recreating dockerplayground_another_1 ... done
$ docker-compose ps
           Name                Command      State   Ports
---------------------------------------------------------
dockerplayground_another_1   /usr/bin/yes   Up           
dockerplayground_main_1      /usr/bin/yes   Up           
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3b256d98bf2c        python:3.5.2        "/usr/bin/yes"      7 seconds ago       Up 6 seconds                            dockerplayground_another_1
dfc04a452547        python:3.5.2        "/usr/bin/yes"      7 seconds ago       Up 6 seconds                            dockerplayground_main_1
$ docker exec -it 3b256d98bf2c ping dfc04a452547
ping: unknown host
$ docker exec -it 3b256d98bf2c ping main
ping: unknown host
$ docker exec -it 3b256d98bf2c ping another
ping: unknown host
$ docker exec -it 3b256d98bf2c ping dockerplayground_another_1
ping: unknown host
$ docker exec -it 3b256d98bf2c ping dockerplayground_main_1
ping: unknown host

If I search up the ip address of the containers through docker network inspect bridge, I can use that to ping as follows.

$ docker exec -it 3b256d98bf2c ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.076 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.046 ms

However, I want to do the same thing through the hostname of the containers. My docker, docker-compose, and OS versions are as follows.

$ docker --version
Docker version 17.12.0-ce, build c97c6d6

$ docker-compose --version
docker-compose version 1.18.0, build 8dd22a9
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial
Kent Shikama
  • 3,910
  • 3
  • 22
  • 55
  • 2
    Try to use a network different from the default (`172.17.0.x`) and you will be able to ping by using the container names. – tgogos Jan 22 '18 at 10:17
  • 1
    Why? Because "Containers on the default bridge network can only access each other by IP addresses, unless you use the --link option, which is considered legacy". Click [here](https://docs.docker.com/network/bridge/#use-the-default-bridge-network) for more info. – Jacob van Lingen Oct 01 '20 at 09:31

3 Answers3

20

Credits to tgogos: I just had to use the non-default bridge.

For completeness, here is my working config.

version: "3"
services:
  main:
    networks:
      test:
    image: python:3.5.2
    entrypoint: /usr/bin/yes

  another:
    networks:
      test:
    image: python:3.5.2
    entrypoint: /usr/bin/yes


networks:
  test:
    driver: bridge

And the ping now works.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
faa9f96d46a9        python:3.5.2        "/usr/bin/yes"      9 seconds ago       Up 9 seconds                            dockerplayground_main_1
5b2d56ac0cd7        python:3.5.2        "/usr/bin/yes"      9 seconds ago       Up 8 seconds                            dockerplayground_another_1
$ docker exec -it faa ping another
PING another (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.054 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.066 ms
Kent Shikama
  • 3,910
  • 3
  • 22
  • 55
  • 1
    The network definition is redundant. If you remove the its specs, as @Kilian answered, you get the default network for free, between the sevices. – Kamafeather Sep 15 '21 at 15:34
  • 1
    @Kamafeather I guess Jacob has already commented it but [default bridge is considered legacy](https://docs.docker.com/network/bridge/#differences-between-user-defined-bridges-and-the-default-bridge). – Ganesh Jadhav Jan 26 '23 at 12:45
  • Good to read, thanks for the link! – Kamafeather Jan 27 '23 at 19:39
9

delete this network_mode: bridge from your compose file, worked for me =).

Kilian
  • 1,753
  • 13
  • 21
  • 4
    Good one. By removing the `network_mode: bridge`, the [default](https://docs.docker.com/compose/networking/) networking of compose takes place: "By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name." – Jacob van Lingen Oct 01 '20 at 09:33
2

Another solution I tried and worked was explicitly linking the containing you want to ping with host name. For example, I have a postgres container, and a server wants to connect to it.

Run the server with the following

docker run --name server --link postgres someserver:latest

In the server container environment, you can then ping with (given postgres is on the same bridge/network and is running)

ping postgres 

Since --link has been deprecated, it is recommended to use network bridge.

docker network create YOURNETWORK
docker run --name postgres --network='YOURNETWORK' postgres:latest
docker run --name server --network='YOURNETWORK' server:latest

then the two containers can ping each other by name.

HarryQ
  • 1,281
  • 2
  • 10
  • 25
  • 5
    Links have been deprecated for years, and this question is a year old and already answered. – BMitch Jan 29 '19 at 13:56