Finding a container’s IP address feels like it should be trivial, and most of the time it is — one docker inspect command away. But I’ve hit enough edge cases over the years (containers with multiple networks, host-mode networking, IPv6-only setups, containers that haven’t even started yet) that I’ve built up a whole toolkit of methods depending on exactly what I need. This guide covers all of them, from the one-liner you’ll use 90% of the time to the deeper debugging techniques for trickier situations.
The Fastest Method: docker inspect
For a container on a standard bridge network, this is the command I reach for first:
docker inspect --format '{{.NetworkSettings.IPAddress}}' my_container
Expected output:
172.17.0.2
This works cleanly for containers attached to the default bridge network. Note the field is empty for containers on user-defined networks, which brings me to the next method.
Getting the IP on a User-Defined Network
If your container is attached to a custom network (which, as covered elsewhere in this series, is the recommended approach for anything beyond quick testing), .NetworkSettings.IPAddress will return an empty string:
docker inspect --format '{{.NetworkSettings.IPAddress}}' my_container
Output:
Instead, drill into the .Networks map, keyed by network name:
docker inspect --format '{{range $net, $conf := .NetworkSettings.Networks}}{{$net}}: {{$conf.IPAddress}}{{"\n"}}{{end}}' my_container
Expected output:
app_net: 172.20.0.2
Or, if you know the exact network name:
docker inspect --format '{{.NetworkSettings.Networks.app_net.IPAddress}}' my_container
Expected output:
172.20.0.2
Full JSON Inspection (When You Need Everything)
Sometimes I want the full picture — gateway, MAC address, subnet mask, all networks at once:
docker inspect my_container --format '{{json .NetworkSettings.Networks}}' | python3 -m json.tool
Expected output (abbreviated):
{
"app_net": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"my_container",
"a1b2c3d4e5f6"
],
"NetworkID": "f3e2d1c0b9a8...",
"EndpointID": "9f8e7d6c5b4a...",
"Gateway": "172.20.0.1",
"IPAddress": "172.20.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:14:00:02",
"DriverOpts": null
}
}
This is genuinely useful when debugging routing issues — the Gateway and IPPrefixLen fields tell you exactly what subnet the container believes it’s on.
Using docker container inspect with -f Shorthand
Functionally identical to docker inspect, but scoped explicitly to containers (useful in scripts to avoid ambiguity with images or networks sharing a name):
docker container inspect -f '{{.NetworkSettings.IPAddress}}' my_container
Method: docker network inspect
If I want to see every container’s IP on a given network at once — useful for auditing a whole application stack — I inspect the network itself rather than each container individually:
docker network inspect app_net --format '{{range .Containers}}{{.Name}}: {{.IPv4Address}}{{"\n"}}{{end}}'
Expected output:
web: 172.20.0.3/16
db: 172.20.0.2/16
Or get the full JSON for the network:
docker network inspect app_net
This shows the subnet, gateway, driver, and every connected container with its IP, which is my go-to when troubleshooting connectivity issues across an entire application.
Method: From Inside the Container
Sometimes the cleanest approach is just asking the container itself. If the image has basic networking tools:
docker exec my_container hostname -i
Expected output:
172.20.0.2
Or, for more detail, using ip addr (needs iproute2, commonly available on Debian/Ubuntu-based images):
docker exec my_container ip addr show eth0
Expected output (abbreviated):
3: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.20.0.2/16 brd 172.20.255.255 scope global eth0
valid_lft forever preferred_lft forever
On minimal images (like alpine or distroless) that lack ip or hostname, I fall back to reading /proc/net:
docker exec my_container cat /proc/net/fib_trie | grep -A1 "32 host LOCAL"
Or, more reliably on truly minimal images with no shell tools at all, use docker inspect from the host instead — there’s no way to exec into a container with literally nothing in it.
Method: Using nsenter (No Tools Inside the Container Needed)
This is my favorite trick for distroless or scratch-based images where docker exec doesn’t even have a shell to run:
PID=$(docker inspect -f '{{.State.Pid}}' my_container)
sudo nsenter -t $PID -n ip addr show
Because this enters the container’s network namespace directly from the host, it works regardless of what’s actually installed inside the container image.
Finding the IP with docker compose
For Compose-managed services, the same docker inspect approach works, just resolving the actual container name first:
docker compose ps -q web
Expected output:
a1b2c3d4e5f6...
Chain it directly:
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker compose ps -q web)
Or, more simply, since Compose service names are already resolvable via DNS on the project’s network, I usually don’t even need the IP for inter-service communication — I just use the service name directly (e.g., db, redis) rather than resolving an IP at all.
Special Case: Host Networking Mode
If a container was started with --network host, it has no separate IP — it shares the host’s network stack entirely:
docker run -d --network host --name host_mode_app nginx
docker inspect --format '{{.NetworkSettings.IPAddress}}' host_mode_app
Expected output:
Empty, as expected — there’s no container-specific IP to report. The container is simply using the host’s own IP addresses.
Special Case: Multiple Networks
A container can be connected to more than one network simultaneously (common for services that need to be on both a “frontend” and “backend” network):
docker network create frontend_net
docker network create backend_net
docker run -d --name multi_net_app --network frontend_net nginx
docker network connect backend_net multi_net_app
Now inspect all its networks:
docker inspect --format '{{range $net, $conf := .NetworkSettings.Networks}}{{$net}}: {{$conf.IPAddress}}{{"\n"}}{{end}}' multi_net_app
Expected output:
frontend_net: 172.21.0.2
backend_net: 172.22.0.2
Scripting: Getting IPs for All Running Containers at Once
A script I keep around for quickly auditing a busy host:
for c in $(docker ps -q); do
name=$(docker inspect -f '{{.Name}}' "$c" | sed 's/^\///')
ips=$(docker inspect -f '{{range $net, $conf := .NetworkSettings.Networks}}{{$net}}={{$conf.IPAddress}} {{end}}' "$c")
echo "$name: $ips"
done
Expected output:
web: app_net=172.20.0.3
db: app_net=172.20.0.2
redis: app_net=172.20.0.4
Getting the IPv6 Address
If your network has IPv6 enabled:
docker network create --ipv6 --subnet 2001:db8:1::/64 ipv6_net
docker run -d --name ipv6_app --network ipv6_net nginx
docker inspect --format '{{.NetworkSettings.Networks.ipv6_net.GlobalIPv6Address}}' ipv6_app
Expected output:
2001:db8:1::2
Finding the Host-Mapped Port Alongside the IP
Often what I actually need isn’t the container’s internal IP at all, but how to reach it from outside — which means combining the IP/port publishing info:
docker port my_container
Expected output:
80/tcp -> 0.0.0.0:8080
For most host-level access, I connect to localhost:8080 or the host’s own IP — I rarely need the container’s internal 172.x address unless I’m debugging container-to-container traffic directly, or working from another container on the same Docker network.
Common Errors and Troubleshooting
Empty output from .NetworkSettings.IPAddress
Almost always means the container is on a user-defined network (not the default bridge) or is using host/none networking. Check which networks it’s on:
docker inspect --format '{{json .NetworkSettings.Networks}}' my_container
“No such container” error
The container name or ID is wrong, or it hasn’t been created yet. List running and stopped containers:
docker ps -a
IP address changes after every restart
This is expected default behavior — Docker doesn’t guarantee IP address stability across restarts on bridge networks unless you assign a static IP. If you need one, assign it explicitly when creating the network and container:
docker network create --subnet=172.30.0.0/16 static_net
docker run -d --name static_app --network static_net --ip 172.30.0.10 nginx
Verify:
docker inspect --format '{{.NetworkSettings.Networks.static_net.IPAddress}}' static_app
Expected output:
172.30.0.10
docker exec “OCI runtime exec failed: exec failed: unable to start container process: exec: no such file or directory”
This means the image has no shell (common with scratch or distroless base images) — use the nsenter method from the host instead, as described above.
Kubernetes Equivalent: Finding a Pod’s IP
For anyone working across both Docker and Kubernetes, the equivalent lookup for a Pod’s IP is:
kubectl get pod my-pod -o jsonpath='{.status.podIP}'
Expected output:
10.244.1.7
Or, for all Pods with their IPs at once:
kubectl get pods -o wide
Conceptually, this maps directly onto docker network inspect — both give you the assigned address within the cluster’s (or Docker network’s) internal addressing scheme, which is generally not meant to be relied upon directly by end users outside the cluster/host.
Best Practices
- Prefer container/service names over raw IPs for inter-container communication whenever possible — IPs on bridge networks aren’t guaranteed stable across restarts, but DNS names are.
- Use
docker network inspectwhen you need a full picture of everything on a given network, rather than querying containers one at a time. - Reserve
nsenterfor genuinely minimal images with no shell — it’s more powerful thandocker execbut requires host root access. - Assign static IPs deliberately only when something genuinely requires IP stability (some legacy apps, specific firewall allow-lists) — don’t do it by default, since it adds operational complexity.
- Remember
--network hostcontainers have no separate IP — don’t waste time debugging an empty.NetworkSettings.IPAddressfield for those. - Script repetitive lookups (like the loop example above) rather than manually inspecting containers one at a time on busy hosts.
Summary
Finding a Docker container’s IP address is usually a one-line docker inspect command, but the exact approach depends on whether the container is on the default bridge network, a user-defined network, multiple networks, or using host/none networking. Beyond the basic lookup, tools like docker network inspect, nsenter, and simple exec-based checks round out a complete toolkit for every situation you’re likely to encounter — including debugging minimal images with no shell at all.
References
- Docker Documentation: docker inspect CLI reference
- Docker Documentation: docker network inspect CLI reference
- Docker Documentation: Networking overview
- Linux man-pages: nsenter(1)
- Kubernetes Documentation: Debug Running Pods