Artigo original: How to Get A Docker Container IP Address - Explained with Examples
O Docker fornece a capacidade e "empacotar" e executar uma aplicação em um ambiente relativamente isolado, chamado de contêiner.
Eu sei o que você está pensando – ah, não, outro artigo explicando o que é o Docker! A gente encontra isso em todo lugar agora!

Mas não se preocupe. Pularemos a parte introdutória. O público alvo desse artigo já deve ter um conhecimento básico sobre o Docker e sobre contêineres.
Mas você já se perguntou sobre como obter o endereço IP de um contêiner do Docker?
Rede do Docker explicada
Primeiro, vamos entender como a rede do Docker funciona. Para isso, vamos nos concentrar na rede bridge
padrão. Ao usar o Docker, se você não especificar um driver, este é o tipo de rede que você usará.

A rede bridge
funciona como uma rede interna privada para o host de modo que os contêineres dentro dele possam se comunicar. O acesso externo é garantido ao expor portas para os contêineres.
As redes bridge são usadas quando suas aplicações rodam em contêineres autônomos que precisam se comunicar.
Na figura acima, db
e web
podem se comunicar entre eles em uma rede bridge criada pelo usuário, chamada mybridge
.
Se você nunca adicionou uma rede no Docker, deverá ver algo semelhante a isso:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
c3cd46f397ce bridge bridge local
ad4e4c24568e host host local
1c69593fc6ac none null local
A rede bridge
padrão está listada, junto com host
e none
. Ignoraremos as outras duas e usaremos a rede bridge
ao chegar aos exemplos.
Endereço IP do contêiner do Docker
Por padrão, o contêiner recebe um endereço IP para cada rede do Docker a qual ele se conecta. Cada rede é criada com uma máscara de sub-rede padrão, usando-a como um pool posteriormente para fornecer o endereço IP.
Em geral, o Docker usa a sub-rede padrão 172.17. 0.0/16 para colocar o contêiner em rede.
Para entender isso melhor, vamos executar um caso de uso real.

Exemplo do Docker
Para ilustrar, usaremos um ambiente de Hive e Hadoop, contendo 5 contêineres do Docker.
Confira o arquivo docker-compose.yml
que estamos prestes a executar:
version: "3"
services:
namenode:
image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8
volumes:
- namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
env_file:
- ./hadoop-hive.env
ports:
- "50070:50070"
datanode:
image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8
volumes:
- datanode:/hadoop/dfs/data
env_file:
- ./hadoop-hive.env
environment:
SERVICE_PRECONDITION: "namenode:50070"
ports:
- "50075:50075"
hive-server:
image: bde2020/hive:2.3.2-postgresql-metastore
env_file:
- ./hadoop-hive.env
environment:
HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore"
SERVICE_PRECONDITION: "hive-metastore:9083"
ports:
- "10000:10000"
hive-metastore:
image: bde2020/hive:2.3.2-postgresql-metastore
env_file:
- ./hadoop-hive.env
command: /opt/hive/bin/hive --service metastore
environment:
SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432"
ports:
- "9083:9083"
hive-metastore-postgresql:
image: bde2020/hive-metastore-postgresql:2.3.0
volumes:
namenode:
datanode:
Ninguém quer ler um arquivo de configuração ENORME, certo? Então, aí vai uma imagem:

Melhor assim! Vamos começar com os contêineres:
docker-compose up -d
Podemos ver 5 contêineres:
$ docker ps --format \
"table {{.ID}}\t{{.Status}}\t{{.Names}}"
CONTAINER ID STATUS NAMES
158741ba0339 Up 1 minutes dockerhive_hive-metastore-postgresql
607b00c25f29 Up 1 minutes dockerhive_namenode
2a2247e49046 Up 1 minutes dockerhive_hive-metastore
7f653d83f5d0 Up 1 minutes (healthy) dockerhive_hive-server
75000c343eb7 Up 1 minutes (healthy) dockerhive_datanode
Agora, vamos conferir as redes do Docker:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
c3cd46f397ce bridge bridge local
9f6bc3c15568 docker-hive_default bridge local
ad4e4c24568e host host local
1c69593fc6ac none null local
Espere aí... tem uma nova rede chamada docker-hive_default
!
Por padrão, o comando docker compose configura uma única rede para seu app. E a rede do app recebe seu nome com base no “nome do projeto”, originário do nome do diretório em que ele está.
Como o nome do nosso diretório é docker-hive
, isso explica a nova rede.
Em seguida, veremos exemplos de como obter o endereço IP do contêiner do Docker.
Como obter o endereço IP do contêiner do Docker - exemplos
Agora que eu já tenho sua atenção, vamos revelar o mistério.

1. Usando docker inspect
O comando docker inspect é uma ótima forma de obter informações de baixo nível sobre os objetos do Docker. Você pode pegar qualquer campo do JSON retornado de maneira bastante direta.
Vamos usá-lo para obter o endereço IP de dockerhive_datanode
?
$ docker inspect -f \
'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
75000c343eb7
172.18.0.5
Você não disse que o Docker usa a sub-rede 172.17. 0.0/16 padrão para colocar o contêiner em rede? Por que o endereço IP retornado é 172.18.0.5 fora dele?

Para responder isso, temos que olhar para nossas configurações de rede:
$ docker network inspect -f \
'{{range .IPAM.Config}}{{.Subnet}}{{end}}' 9f6bc3c15568
172.18.0.0/16
Executamos esse exemplo em uma máquina virtual do Compute Engine. Neste teste, a rede do Docker foi atribuída a uma sub-rede diferente: 172.18.0.0/16. Isso explica a questão!
Além disso, podemos procurar os endereços IP na rede docker-hive_default
.
Assim, não precisamos procurar o IP de cada contêiner individualmente:
$ docker network inspect -f \
'{{json .Containers}}' 9f6bc3c15568 | \
jq '.[] | .Name + ":" + .IPv4Address'
"dockerhive_hive-metastore-postgresql:172.18.0.6/16"
"dockerhive_hive-metastore:172.18.0.2/16"
"dockerhive_namenode:172.18.0.3/16"
"dockerhive_datanode:172.18.0.5/16"
"dockerhive_hive-server:172.18.0.4/16"

Caso não tenha percebido, usamos a ajuda do jq para analisar o objeto de mapa Containers
.
2. Usando docker exec
No exemplo a seguir, trabalharemos com o dockerhive_namenode
.
$ docker exec dockerhive_namenode cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 607b00c25f29
3. Dentro do contêiner do Docker
$ docker exec -it dockerhive_namenode /bin/bash
# rodando dentro do contêiner dockerhive_namenode
ip -4 -o address
7: eth0 inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
Podemos até encontrar os endereços IP de outros contêineres que estão dentro da mesma rede:
Nó dos dados (data node)
# rodando dentro do contêiner dockerhive_namenode
ping dockerhive_datanode
PING dockerhive_datanode (172.18.0.5): 56 data bytes
64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.092 ms
Metastore do Hive
# rodando dentro do contêiner dockerhive_namenode
ping dockerhive_hive-metastore
PING dockerhive_hive-metastore_1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.087 ms
Servidor do Hive
# rodando dentro do contêiner
ping dockerhive_hive-server
PING dockerhive_hive-server (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.172 ms
Para encerrar
Todos os exemplos foram executados em uma VM de uma distribuição Linux no Compute Engine. Se você executar os exemplos nos ambientes macOS ou Windows, os comandos dos exemplos podem mudar um pouco.
Lembre-se, também, de que esses endereços IP dos exemplos dados são internos à rede docker-hive_default
usada na amostra. Por isso, se você tiver um caso de uso para conectar esses contêineres externamente, precisará usar o IP externo da máquina do host (levando em conta que você estará expondo as portas dos contêineres corretamente).
Se estiver usando kubernetes, por exemplo, para gerenciar seus contêineres do Docker, permita que ele trate dos endereços IP para você.
* Ilustrações de icons8.com feitas por Murat Kalkavan.