How to Ping Other Containers in a Docker Network Through Their Hostname

How can I ping other containers in a docker network through their hostname?

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

cant ping docker container by name from host

Option A: run a DNS proxy server container

Here is a DNS proxy server project that can do this: https://github.com/mageddo/dns-proxy-server

First, you need to start the DNS proxy server:

docker run --rm --hostname dns.mageddo -v /var/run/docker.sock:/var/run/docker.sock -v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server

Then, run a dummy container and assign it a --hostname for testing purpose:

docker run -d --hostname=this-can-be-resolved-from-host nginx

Finally, try to resolve/ping/curl the name you assigned to the nginx container in the previous step, from your host machine:

neo@neo-desktop:~$ nslookup this-can-be-resolved-from-host
Server: 172.17.0.4
Address: 172.17.0.4#53

Non-authoritative answer:
Name: this-can-be-resolved-from-host
Address: 172.17.0.3
Name: this-can-be-resolved-from-host
Address: 172.17.0.3

neo@neo-desktop:~$ ping this-can-be-resolved-from-host
PING this-can-be-resolved-from-host (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3 (172.17.0.3): icmp_seq=1 ttl=64 time=0.032 ms
neo@neo-desktop:~$ curl this-can-be-resolved-from-host
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[...]

Option B: Run an injector that adds the container names directly in the hosts file, on the docker host:

(solution found by the OP @Tokyo Developer)

Here is a simple "etc/hosts" file injection tool: https://github.com/dvddarias/docker-hoster

Run the injector container:

docker run -d \
-v /var/run/docker.sock:/tmp/docker.sock \
-v /etc/hosts:/tmp/hosts \
dvdarias/docker-hoster

Run a dummy container and assign it a --hostname for testing purpose:

docker run -d --hostname=this-can-be-resolved-from-host nginx

Try to resolve the hostname AND the container name assigned to the nginx container in the previous step, from your host machine:

nslookup this-can-be-resolved-from-host
Server: 127.0.0.53
Address: 127.0.0.53#53

Non-authoritative answer:
Name: this-can-be-resolved-from-host
Address: 172.17.0.3
nslookup keen_lamarr
Server: 127.0.0.53
Address: 127.0.0.53#53

Non-authoritative answer:
Name: keen_lamarr
Address: 172.17.0.3

How to enable docker containers ping each other via their host names?

The link option is deprecated so I suggest you to use the --network-alias option in addition to the --name flag (see the documentation here and here for more info).

For example, admiting you have a network called test, you can run these two commands (in two separate terminal)

docker run -it --rm --name debian1 --network=test --network-alias=debian1 debian:jessie /bin/bash
docker run -it --rm --name debian2 --network=test --network-alias=debian2 debian:jessie /bin/bash

Then you will be able to ping containers according to their network-alias

Docker networks: How to get container1 to communicate with server in container2

Since you started the two containers on the same --network, you can use their --name as hostnames to talk to each other. If the service inside the second container is listening on port 8080, use that port number. Remappings with docker run -p options are ignored, and you don't need a -p option to communicate between containers.

In your Apache config, you'd set up something like

ProxyPass "/" "http://geoserver:8080/"
ProxyPassReverse "/" "http://geoserver:8080/"

It's not usually useful to look up the container-private IP addresses: they will change whenever you recreate the container, and in most environments they can't be used outside of Docker (and inside of Docker the name-based lookup is easier).

(Were you to run this under Docker Compose, it automatically creates a network for you, and each service is accessible under its Compose service name. You do not need to manually set networks: or container_name: options, and like the docker run -p option, Compose ports: are not required and are ignored if present. Networking in Compose in the Docker documentation describes this further.)

Can't resolve set hostname from another docker container in same network

Hostname is not used by docker's built in DNS service. It's a counterintuitive exception, but since hostnames can change outside of docker's control, it makes some sense. Docker's DNS will resolve:

  • the container id
  • container name
  • any network aliases you define for the container on that network

The easiest of these options is the last one which is automatically configured when running containers with a compose file. The service name itself is a network alias. This lets you scale and perform rolling updates without reconfiguring other containers.

You need to be on a user created network, not something like the default bridge which has DNS disabled. This is done by default when running containers with a compose file.

Avoid using links since they are deprecated. And I'd only recommend adding host entries for external static hosts that are not in any DNS, for container to container, or access to other hosts outside of docker, DNS is preferred.

docker-compose hostname to communicate between containers works with postgres but not app

Your app container is most likely not running. Its appearance in docker network inspect means that the container exists but it may be exited (i.e. is not running). You can check with docker ps -a, for example:

$ docker ps -a
CONTAINER ID ... STATUS ... NAMES
fe908e014fdd Exited (0) Less than a second ago so_app_1
3b2ca418c051 Up 2 minutes so_postgres_1
  • container app exists but is not running: you won't be able to ping it even if it exists in the network
  • container postgres exists and is running: you will be able to ping it

It's probably due to the fact that docker-compose run --rm --service-ports nuxt bash will only create and run the nuxt container, it won't run app nor postgres. You are able to ping postgres because it was already running before you used docker-compose run nuxt bash

To be able to ping other containers after running docker-compose run nuxt ..., you should either:

  • Have the other containers already running before (such as by using docker-compose up -d)
  • Have the other containers depends_on the container you are trying to run, for example:

    nuxt:
    image: node:latest
    ports:
    - "3000:3000"
    # this will ensure posgres and app are run as well when using docker-compose run
    depends_on:
    - app
    - nuxt

Even with that, your container may fail to start (or exit right after start) and you won't be able to ping it. Check with docker ps -a that it is running and docker logs to see why it may have exited.

Can't ping Docker containers via hostnames/names

You can check the network-scope alias which comes with docker network connect and docker run.

Starting a container with an alias allows your NGinx to reverse proxy to that alias in its config.

At runtime, that alias will resolve to the container that you started later.

See an example in "Docker Networking: Auto-discovering host names in a bridge network".

Note that you will need a key-value store to manage your container in a docker 1.10+ network.


Note (July 2016) with docker 1.12 and its swarm mode, it becomes even simpler.

See for instance "The beautiful networking stack in Docker Swarm mode"

The docker swarm will define an overlay network and a key-value store for you! The containers will see each others.

Another concrete example: "NGINX as a Reverse Proxy for Docker Swarm Clusters"



Related Topics



Leave a reply



Submit