The Default Bridge Trap
Why http://api/ Can't Be Found
Scenario: Your nginx proxy forwards tohttp://api/. Both containers are running. nginx crash-loops withhost 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 bridge | user-defined bridge | |
|---|---|---|
| Name → IP resolution | ❌ | ✅ built-in DNS |
| Isolation | all containers together | only members see each other |
| Connect/disconnect live | limited | docker 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