Networking
Drivers and name resolution
Bridge is the default. A user-defined bridge network gives containers embedded DNS, so they reach each other by container name or network alias. The legacy default bridge network does not - that is why --link existed, and why almost every "ping by name fails" question turns on which network was used. host removes network isolation and makes -p meaningless, none leaves only a loopback stack, overlay spans swarm nodes, and macvlan gives containers real L2 presence on the physical LAN.
Publishing: -p 8080:80 maps host 8080 to container 80, -p 127.0.0.1:8080:80 restricts to loopback, -P publishes all EXPOSEd ports to random host ports. EXPOSE alone publishes nothing - it is documentation.
Useful commands: docker network create --driver bridge --subnet 10.10.0.0/16 --gateway 10.10.0.1 mynet, docker network connect and disconnect, docker network inspect for IPAM config and attached containers, docker network prune.
Traps
A container joins one network at creation but can be attached to more afterwards with connect. Overlay networks require swarm mode unless created with --attachable. Published ports bind 0.0.0.0 by default - that is a security question wearing a networking costume. Inside a container, the embedded resolver lives at 127.0.0.11; editing /etc/hosts and /etc/resolv.conf from the host fights it.
Rule of thumb
If two containers must talk by name, put them on the same user-defined network - do not publish ports just to let siblings chat.