IntermediateLesson 6 of 16

🌐 Docker Networking, Port Mapping and Service Discovery

Learn how containers communicate with each other and the outside world — bridge networks, host networking, port mapping, and DNS-based service discovery.

🧒 Simple Explanation (ELI5)

Every container gets its own private network address — like a separate apartment with its own intercom number. Port mapping is like telling the building front desk: "forward calls on the front door buzzer (host port 8080) to apartment 101 (container port 80)." User-defined bridge networks give containers a shared internal phone book — they find each other by name, not number.

💡
Key rule

Containers on the same user-defined bridge network can reach each other by container name (DNS). Containers on the default bridge network can only reach each other by IP address — names don't work there.

🔧 Network Types

Docker Network Drivers
bridge
Default. Isolated virtual network on host. Port mapping required for external access.
host
Shares host network stack. No port mapping. Best performance. Less isolation.
none
No networking at all. Fully isolated.
overlay
Multi-host. Used by Docker Swarm and some Compose setups.

💻 Networking Commands

bash
# ---- Port Mapping ----
# Map host port 8080 to container port 80
docker run -d -p 8080:80 nginx

# Map to a specific host interface only (more secure)
docker run -d -p 127.0.0.1:8080:80 nginx

# Map multiple ports
docker run -d -p 8080:80 -p 8443:443 nginx

# ---- User-defined Bridge Networks ----
# Create a network
docker network create myapp-network

# Connect containers to shared network (they can reach each other by name)
docker run -d --name db --network myapp-network postgres:15
docker run -d --name api --network myapp-network myapi:latest
# The api container can now reach postgres at hostname "db"

# List networks
docker network ls

# Inspect a network (see connected containers and IP ranges)
docker network inspect myapp-network

# Connect a running container to a network
docker network connect myapp-network my-container

# Remove a network
docker network rm myapp-network

# ---- DNS Service Discovery ----
# Inside api container: reach db by name
# curl http://db:5432 or psql -h db -U postgres

🧪 Hands-on Exercises

  1. Create a user-defined bridge network. Run a Redis container and a Node.js app on the same network — connect using the Redis container name as hostname.
  2. Run nginx mapped to localhost only (-p 127.0.0.1:8080:80) and verify it is not accessible from another machine on the network.
  3. Use docker network inspect to find container IPs on a network.
  4. Run two containers: one on the default bridge and one on a user-defined network. Verify that the default bridge containers cannot reach each other by name.

🐛 Debugging Scenario

Problem: API container fails to connect to DB container with "connection refused on host db".

bash
# Step 1: check both containers are on the same network
docker network inspect myapp-network
# Look for both container names in the Containers section

# Step 2: confirm the DB is running and healthy
docker ps
docker logs db

# Step 3: test DNS resolution inside the API container
docker exec -it api nslookup db
docker exec -it api curl -v db:5432

# Common causes:
# - Containers are on different networks (or default bridge where DNS does not work)
# - DB is not running or crashed at startup
# - API started before DB was ready (use health checks and depends_on in Compose)

🎯 Interview Questions

What is the difference between bridge and host networking?

Bridge creates an isolated virtual network on the host — containers get their own IP, external access requires port mapping. Host mode removes the network namespace — the container shares the host's IP and ports directly. Host mode has no overhead and better performance, but less isolation. Use bridge for most workloads; host for high-throughput scenarios or when the container needs to bind to specific host interfaces.

How does Docker's DNS-based service discovery work?

Docker runs an embedded DNS server at 127.0.0.11 within user-defined bridge networks. When a container joins a user-defined network, Docker registers the container name as a DNS record. Containers on the same network can resolve each other by container name. This does NOT work on the default bridge network — IP addresses must be used there instead.

Scenario: You need to expose a container port only on localhost. How?

Use the host IP prefix in the port mapping: -p 127.0.0.1:8080:80. This binds the host port only to the loopback interface, so the container is accessible locally but not from other machines. This is important for admin interfaces, debugging endpoints, and internal services that should not be publicly exposed even on a development machine.

📋 Summary