The Default Bridge Trap

Why http://api/ Can't Be Found

Scenario: Your nginx proxy forwards to http://api/. Both containers are running. nginx crash-loops with host not found in upstream "api". The code is fine, the containers are fine - the network is the bug.

When you run a container without specifying a network, Docker attaches it to the default bridge - a private virtual network that ships out of the box. It does let containers talk to each other, but only by numeric IP address (e.g. 172.17.0.2), because it provides no name resolution (no DNS, the system that turns a friendly name into an IP address, the same thing that turns google.com into a real address on the internet). Ask for a container by name on the default bridge, and there's simply nothing to answer. That convenience is a feature of a different kind of network, one you create yourself: a user-defined network:

$ docker network create shopnet          # user-defined bridge
$ docker run -d --name api --network shopnet my-api
$ docker run -d --name web --network shopnet -p 8080:80 my-proxy
# now, inside web:  http://api/  resolves ✓
default bridgeuser-defined bridge
Name → IP resolution❌✅ built-in DNS
Isolationall containers togetheronly members see each other
Connect/disconnect livelimiteddocker network connect/disconnect
Tip: Rule of thumb: never deploy multi-container apps on the default bridge. One docker network create fixes discovery and gives you isolation between app stacks for free. (Compose does this automatically.)
$ docker network ls
$ docker network inspect shopnet     # members, subnet, IPs