Chapter 17Lesson 04~130 minutes

Container Networking Foundations: Bridge, Host, None, User-Defined Networks, Endpoints, and Namespaces: Diagnostics, Failure Modes, Security, and Performance

Diagnose Docker connectivity failures causally by proving application listening state, namespace/endpoint attachment, routes/DNS, host firewall/backend behavior, and exposure separately.

DiagnosticsNamespacesFirewall backendIsolationEvidence

Learning objectives

  • Use an evidence-first sequence that proves listener/process state before blaming Docker networking.
  • Diagnose wrong network membership and network-scoped DNS failures without recreating containers blindly.
  • Explain why localhost, hard-coded container IPs, flat network membership, and host mode commonly produce misleading troubleshooting paths.
  • Separate internal container connectivity from host port publishing/firewall behavior so Chapter 19 concerns do not obscure Chapter 17 evidence.
  • Preserve first-failure network, process, log, endpoint, route, DNS, and platform evidence before applying the smallest correction.
Evidence-first rule. Do not start with firewall edits, daemon restarts, container recreation, or port publication. First prove what process is listening, which network endpoint exists, what route/DNS the container sees, and whether the peer is on the same intended network.

1. Diagnostic sequence

  1. Preserve first-failure logs, container IDs, image digests, network IDs, endpoint attachments, and timestamps.
  2. Confirm docker version, docker info, and selected context/platform.
  3. Prove the application listens locally inside the container.
  4. Inspect NetworkSettings.Networks for both endpoints.
  5. Inspect the Docker network object, subnet/gateway, and connected containers.
  6. Inspect container routes and /etc/resolv.conf; test network-scoped name resolution.
  7. Only after internal connectivity is proven should you move outward to published ports/NAT/firewall/external clients.
  8. Apply the narrowest correction and rerun only the failing scope.

2. Intentionally broken example: peers on different networks

This failure is safe and local. The server and client run correctly, but each joins a different user-defined bridge. The client attempts to reach the server by name.

docker network create --label devops-academy.lab=network17-broken da-net17-a
docker network create --label devops-academy.lab=network17-broken da-net17-b

docker run -d \
  --name da-net17-broken-server \
  --network da-net17-a \
  --label devops-academy.lab=network17-broken   busybox:1.36.1 sh -c   'mkdir -p /www; echo ok > /www/index.html; exec httpd -f -p 8080 -h /www'

docker run -d --name da-net17-broken-client   --network da-net17-b --label devops-academy.lab=network17-broken   busybox:1.36.1 sleep 3600

# Preserve the first failure:
docker exec da-net17-broken-client sh -c   'wget -qO- -T 2 http://da-net17-broken-server:8080/ || true'   > first-failure.txt 2>&1

docker inspect da-net17-broken-server --format '{{json .NetworkSettings.Networks}}'   > server-networks.json
docker inspect da-net17-broken-client --format '{{json .NetworkSettings.Networks}}'   > client-networks.json
docker network inspect da-net17-a da-net17-b > network-objects.json

The evidence shows a healthy server process on network A and a client on network B. There is no reason to rebuild either image or publish port 8080 to the host.

Least destructive correction: if design intent says the client belongs on A, add that endpoint and retest:

docker network connect da-net17-a da-net17-broken-client
docker exec da-net17-broken-client wget -qO- http://da-net17-broken-server:8080/

docker inspect da-net17-broken-client --format '{{json .NetworkSettings.Networks}}'   > client-networks.fixed.json

3. Failure: “localhost should reach the other container”

If a process in client connects to 127.0.0.1:8080, it targets client's own loopback. Diagnose this before changing networks: inspect the intended service address/name and verify both endpoints share the intended network. Use the server's network-scoped name, not another container's loopback.

4. Failure: durable configuration uses a container IP

An IP captured from docker inspect is excellent evidence but poor durable service identity. Container recreation can allocate a new address. If an application config contains 172.x.y.z only because that happened to work yesterday, fix the configuration boundary: use a network-scoped name/alias and preserve the network identity in deployment evidence.

5. Failure: every service joins one flat bridge

Flat membership often “fixes” connectivity by removing intended isolation. The security cost is that every member can attempt to reach every other member's listening ports. Model trust zones explicitly. A frontend that needs API access does not automatically need database or admin-tool access.

6. Failure: debugging published ports before proving the internal path

A host publication problem belongs farther out in the chain than an application listener or endpoint membership problem. Before touching -p, NAT, or firewall policy, prove:

  • the process is running and listening on the expected container address/port;
  • a same-network peer can reach it where appropriate;
  • the container is attached to the expected Docker network;
  • the desired host exposure is actually part of the design.

Chapter 19 handles port publishing/NAT/firewall exposure in depth. Keeping those concerns separate prevents destructive “network fixes.”

7. Failure: treating host networking as portable

A script that assumes --network host behaves identically on Linux Engine, Docker Desktop, and Windows containers is not portable. Preserve platform/version evidence. On Desktop, host networking must be enabled, is layer-4 only, and is incompatible with some isolation features. The correction may be a user-defined bridge plus explicit publication, not a daemon setting change.

8. Failure: modifying firewall rules first

Docker warns against editing Docker-created firewall rules. Disabling its firewall management is not a normal troubleshooting step and can break bridge connectivity. Record whether the host uses the default iptables backend or an intentionally configured nftables backend, but do not mutate host policy merely to make a disposable lab pass.

9. Performance reasoning without premature host mode

If latency/throughput is a real concern, measure before changing isolation. Compare application latency, CPU, connection rate, NAT overhead, DNS resolution, and packet loss under controlled load. Host mode can remove NAT/userland-proxy overhead in some cases, but an application bottleneck, DNS delay, MTU issue, or storage wait will not be fixed by collapsing the network namespace boundary.

10. Cleanup the broken example

docker rm -f da-net17-broken-server da-net17-broken-client 2>/dev/null || true
docker network rm da-net17-a da-net17-b 2>/dev/null || true

docker ps -a --filter label=devops-academy.lab=network17-broken
docker network ls --filter label=devops-academy.lab=network17-broken
Next lesson

Next: Checkpoint Lab

Use the evidence sequence in a checkpoint: two isolated bridges, one dual-homed test container, explicit predictions, per-endpoint route/DNS evidence, and no forwarding or broad host changes.

Knowledge check

A server answers on its own loopback but a client cannot resolve its name. What should you inspect before port publishing?

Why is docker network connect a better fix than recreating both containers in the intentionally broken example?

Why is a hard-coded container IP both useful and dangerous?

Why should a flat “everything network” be treated as a security smell?

When should firewall/NAT troubleshooting begin?

Official references and version notes

Version baseline checked 2026-09-21.

Docker Engine 29.8.1 is the current Engine release baseline used for version-sensitive discussion. Docker Engine on Linux uses iptables by default for bridge-network firewall rules; the nftables backend introduced in Engine 29 remains experimental. Docker Desktop host networking is supported from Desktop 4.34+ as an opt-in feature and operates at layer 4. Always record the installed Engine/Desktop version and actual network/firewall state before drawing conclusions.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.