Here: where Docker connected both containers and how they see each other.
Each container has its own network interface and its own address — its own network namespace. A container started without the --network option is connected by Docker to the bridge network. On the host this is the virtual switch docker0, and each container is wired to it with a veth pair. Addresses in this network come from 172.17.0.0/16.
docker network ls lists Docker's networks: besides bridge there are always host (the container sits right in the host's network) and none (no network). docker network inspect shows who is connected to a network and with which addresses.
Connect to the database by address
See who is connected to the bridge network and with which addresses, connect from app to db by address and read /etc/resolv.conf in app.
A program asks for a name's address from the DNS servers in /etc/resolv.conf (name resolution). On the default network Docker puts the host's servers into the container. Our host has none of its own, so the fallback 8.8.8.8 and 8.8.4.4 are there — that is what the line # Used default nameservers. says. Only Docker knows the name db; the internet has no such name. The options line was added by the preparation: the machine has no network, and without it nc would wait 10 seconds for these servers to answer.