Container Networking and DNS
Docker networking decides how containers find each other, how ports reach the outside world, and how host firewalls interact with container traffic. Use user-defined networks for name resolution and isolation, publish only what must be public, and remember that Docker's NAT rules sit in front of host firewalls like ufw.
Key points
- 1
Containers without
--networkjoin the defaultbridge, where names don't resolve; user-defined bridges add DNS by name or alias through the embedded server at127.0.0.11and isolate unrelated stacks. - 2
-p host:container[/proto]publishes to every host address (0.0.0.0and[::]) by default; prefix127.0.0.1:to keep a port host-only (reliable from Engine 28.0.0).EXPOSEonly documents, and-Ppublishes exposed ports to random host ports. - 3
Inside a container,
localhostis the container itself. Apps must listen on0.0.0.0to receive published traffic, and on Linux you reach host services through--add-host host.docker.internal:host-gateway(Docker Desktop adds that name automatically). - 4
Containers on different bridge networks talk only through published ports; attach a container to several networks (an
--internalone for backends) and pin the default gateway withgw-priority. - 5
Published traffic is DNAT-ed in the nat table and forwarded, so ufw's INPUT rules never see it. Put custom filters in
DOCKER-USER, which runs before Docker's rules and sees the post-DNAT container address and port. - 6
--network hostshares the host stack (ports are ignored),noneleaves only loopback,container:<name>shares another container's stack, overlay needs swarm mode plus--attachablefor standalone containers, and macvlan containers can't talk to their own host. - 7
Debug minimal images by running a tools container such as netshoot with
--network container:<name>, and confirm membership withdocker network inspect.
Common traps
Publishing a port on Ubuntu with ufw enabled exposes it to the internet anyway: Docker's DNAT diverts the traffic before ufw's INPUT rules.
--dns 127.0.0.1points at the container's own loopback, not the host's local resolver.Rules appended to FORWARD, or
DOCKER-USERrules matching the original host port, don't filter published traffic: match the container port or use conntrack--ctorigdstport.
Test yourself on Container Networking and DNS
Ten questions, with the answer and explanation after each one.