Skip to main content

Doing Things in Docker

How to Get Docker Container's IP Address

Getting the IP address of a docker container is easy but it is important to understand a few things about docker networks.

Wondering what's the IP address of your running docker container? You can inspect the running container to get that information.

sudo docker container inspect container_name_or_ID
Don't know the container's name or ID? Use the command sudo docker ps.

The inspect command gives you many details about the container you are inspecting. Go towards the end and look into the Networks section to get the container's IP address.

You may also use grep command to get just the lines matching the string "IPAddress".

Don't be alarmed if your container has more than one IP address. That's not unusual. To understand that, you need to understand how containers communicate with each other.

I'll explain that to you in the next section followed by some other methods of getting the IP address of a running docker container.

How docker containers communicate?

Docker is a tool for packaging and delivering software to the masses using containerization technology. Software can have a multitude of purposes, from possibly simple text processing to a full web server, hosting your private files. Each of these softwares is broken down into microservices and then packaged as containers. Depending on the purpose of the software, one service may need to communicate with another.

For example, consider WordPress. There are two services, one is the web server that serves the frontend, and another is the backend, the database. The frontend has to communicate with the database, otherwise, it just won't work.

This communication is achieved by having at least two network interfaces associated with each of these two containers, both interfaces being connected to the same network. This network is called a "docker network".

Docker network

Think of docker network as a pool of available IP addresses. If two containers take on IP addresses from the same pool, they're going to be able to communicate with each other.

There are mainly two types of networks, the default or predefined networks and the user-defined networks.

You can get the list of networks using the following command

docker network ls

Consider my list below:

❯ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
272ff2e44dc2   bridge    bridge    local
5e4a3f5e99dd   host      host      local
cdaef1e49ddc   none      null      local

Ignore the last two and focus on the first network. The bridge network is the default network every container is going to be connected to if none is specified explicitly. You can get more details about this network by running the docker network inspect bridge command.

I'm going to filter the output since for this demonstration I don't need all the data that inspect is going to explode out.

❯ docker network inspect -f '{{json .IPAM.Config}}' bridge | jq -r .[].Subnet
172.17.0.0/16
If you don't have jq installed, please install it using your distribution's package manager.

Each of these docker networks has a subnet, in the case of the bridge network, this subnet is 172.17.0.0/16. This means there are a total of 65,534 - 1 = 65,533 usable hosts or IP addresses. I deducted one since 172.17.0.1 is allocated for the gateway. You can see that as well using the following command

docker network inspect -f '{{json .IPAM.Config}}' bridge | jq -r .[].Gateway

Checking your docker container's IP address

There are a couple of ways you can check the IP address[es] associated with your container, here is a list of all of them including command examples.

Method 1: By inspecting the container

The inspect sub-commands of docker are extremely helpful. A container can be inspected using the docker container inspect [CONTAINER ID]|[CONTAINER NAME] command.

Inspecting a container means getting as much information as possible about the container, from ports, environment variables to mount points, cgroup data, etc. IP address can be extracted from it.

If you run the inspect command on a container, you'll get a bunch of information, in JSON format. Scroll down until you find the key NetworkSettings, there look for the sub-key IPAddress. That's your container's IP address.

The command to execute looks like the following

docker container inspect [CONTAINER ID]|[CONTAINER NAME]

Here's my output (truncated)

> docker container inspect ubuntu-ip
.
.
.
"NetworkSettings": {
.
.
.
            "IPAddress": "172.17.0.2",
.
.
.

Instead of scrolling through all that, you can filter the output like this:

docker container inspect -f '{{ .NetworkSettings.IPAddress }}' CONTAINER_ID_OR_NAME

Here's a filtered output:

❯ docker container inspect -f '{{ .NetworkSettings.IPAddress }}' ubuntu-ip 
172.17.0.2

If you want to get an IP address associated with a specific network, use a command like the following

docker container inspect -f '{{ .NetworkSettings.Networks.[NETWORK NAME].IPAddress }}' CONTAINER_ID_OR_NAME

A sample output:

❯ docker container inspect -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}' ubuntu-ip 
172.17.0.2

method 2: Using the container's shell

This is the most straightforward method, but also something I don't recommend.

In this method, you attach your stdin|stdout with the container's and run the ip command (or some other command that shows the IP addresses associated with the NICs). This is the generic way of knowing the IP address in Linux command line.

The reason I don't recommend this is that many images are quite lightweight, and don't contain the ip command (or something similar).

Take the ubuntu:20.04 image as an example, start a container like the following

docker run --rm --name ubuntu-ip -d ubuntu:20.04 sleep 1d

To keep the container running I used the sleep 1d command.

Now start a shell process inside the container and attach your stdin|stdout like so

docker exec -ti ubuntu-ip sh

Once you're in this container, try running ip or ifconfig. You'll see something like the following:

❯ docker exec -ti ubuntu-ip sh
# ip
sh: 1: ip: not found
# ifconfig
sh: 2: ifconfig: not found

To get those commands to work, you need to install the relevant packages. To get ip command, install the iproute2 package and rerun the command as ip a

# apt update -qq                                       
6 packages can be upgraded. Run 'apt list --upgradable' to see them.
# apt install iproute2 -yqq
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

Now you can see the IP address associated with the card eth0@if5 being 172.17.0.2.

📄
Notice the network this container is part of. Since I did not create and connect a user-defined network to this container, it was connected to the bridge network, which is why the network of this IP is 172.17.0.0

This method surely works, although it's more work and not very reproducible, it's intuitive. The next method should be much better compared to this one.

Method 3: By inspecting the network itself

Whenever a container gets connected to a network, that connected container is visible from the network as well, along with the IP address allocated to those containers.

Since my container is connected to the bridge network, I can inspect the network with the following command

docker network inspect [NETWORK NAME][NETWORK ID]

Here instead of an id, I'll use the name, bridge

docker network inspect bridge

Instead of scrolling down to the Containers section, I'll use jq to filter the output this time.

❯ docker network inspect bridge | jq .[].Containers
{
  "1c76f35ce42ca0d31cfcc79da80eadfa4f69cb82e292e249ee1bd75d83a8e4ba": {
    "Name": "ubuntu-ip",
    "EndpointID": "44d6b85348d6274b4ee779f9d3617d184ccfd3bad228ee652141d9b4157c50ae",
    "MacAddress": "02:42:ac:11:00:02",
    "IPv4Address": "172.17.0.2/16",
    "IPv6Address": ""
  },
  "50a4f195d8eae6b6b714e8aa058c6058dbe91d0a272c8ca826d4442df1c63885": {
    "Name": "ip",
    "EndpointID": "d4e72a4df81ee7023386df9d96676d9c291e2902349eb453338b8e0145a610fd",
    "MacAddress": "02:42:ac:11:00:03",
    "IPv4Address": "172.17.0.3/16",
    "IPv6Address": ""
  }
}

To demonstrate this, I deployed another container with the name ip. You can see the containers and IP addresses in the above JSON object. Now extracting the IP of a specific container is slightly harder here.

If you know the container id, you can use jq like this

docker network inspect bridge | jq '.[].Containers."[CONTAINER ID]".IPv4Address'

Here's an example

❯ docker network inspect bridge | jq '.[].Containers."1c76f35ce42ca0d31cfcc79da80eadfa4f69cb82e292e249ee1bd75d83a8e4ba".IPv4Address' -r
172.17.0.2/16

Most of the time you can not remember the container id, so if you want to get the IP from only the container name, you need some knowledge of jq (or just reuse the following command).

docker network inspect -f '{{json .Containers}}' bridge | \
    jq '..|if type == "object" and has("Name") then select(.Name=="[CONTAINER NAME]") | .IPv4Address else empty end' -r

Place the container name in the select function and see the magic happen.

❯ docker network inspect -f '{{json .Containers}}' bridge | \
    jq '..|if type == "object" and has("Name") then select(.Name=="ubuntu-ip") | .IPv4Address else empty end' -r

172.17.0.2/16

Which method do you prefer? Method 1 probably

Those were all the methods through which you can get the IP address[es] of docker containers. The second method although intuitive isn't reproducible. Most of the time it's the first method that gets used since it's the easiest and gets the job done.

But there may come a time when you'd want to check what some containers are connected to a certain network and get the IP addresses on that network. In that case, inspecting the network and getting the IPs makes sense. You can get all the container names and IPs allocated to them from a network like this

❯ docker network inspect -f '{{json .Containers}}' bridge | \
    jq '.. | if type=="object" and has("Name") then {(.Name): .IPv4Address} else empty end'

{
  "ubuntu-ip": "172.17.0.2/16"
}
{
  "ip": "172.17.0.3/16"
}

Change bridge to some other network, and you'll get all the containers and their IP addresses like this.

That's it for today. I hope this article was helpful to you. If you have any questions, do let me know in the comments down below.