Communication Models Between Containers

Containers don’t just run within their own networks—they need to discover and communicate with one another. Understanding how containers communicate with each other is the foundation for building a microservices architecture.

1. What You'll Learn


2. A True Story from a Microservices Developer

(1) Pain Point: The three microservices are not connected to each other

Charlie deployed three microservice containers: API Gateway, User Service, and Order Service. API Gateway could access the User Service, but the requests always timed out. After two hours of troubleshooting, he discovered that API Gateway had exposed a port but the firewall was not enabled, the User Service was using the wrong container name, and the Order Service was on a different network.

(2) Solutions for Systematic Network Scanning

Bob taught him a network troubleshooting process: container name → DNS → network → port.

BASH
# Step 1: Verify DNS resolution
docker exec api nslookup user-service

# Step 2: Test network connectivity
docker exec api ping -c 2 user-service

# Step 3: Test port connectivity
docker exec api nc -zv user-service 8080

(3) Benefits: Network troubleshooting time reduced from 2 hours to 10 minutes

With a systematic troubleshooting process in place, the time it took Charlie to troubleshoot network issues dropped from 2 hours to 10 minutes.


3. Three Methods of Inter-Container Communication

(1) Comparison of Methods

100%
graph TB
    subgraph Method1["① --link (Legacy, Deprecated)"]
        L1["Container A"] -->|"env vars + /etc/hosts"| L2["Container B"]
    end
    subgraph Method2["② Custom Network + DNS (Recommended)"]
        D1["Container A"] -->|"DNS auto-resolve"| D2["Container B"]
    end
    subgraph Method3["③ Exposed Port + Host IP"]
        E1["Container A"] -->|"host:port"| E2["Container B<br/>(via host bridge)"]
    end
Method Principle DNS Status Recommendation
--link Environment Variables + hosts Injection ❌ Obsolete
Custom Network DNS Docker Built-in DNS ✅ Recommended ⭐⭐⭐
Host Port Forwarding Container→Host→Container Available ⭐⭐

BASH
# Legacy link: B can reach A by hostname
docker run -d --name db postgres:15-alpine
docker run -d --name web --link db:database nginx:alpine

# web can use "database" as hostname (via /etc/hosts)
docker exec web cat /etc/hosts
⚠️ Note: --link has been deprecated and is used solely for historical reference. It only supports one-way connections (web→db, not db→web), and the hosts file is not updated when the IP address changes after the container restarts. Always use a custom network instead.**


5. A Detailed Guide to Custom Network DNS

(1) The DNS Resolution Process

100%
graph LR
    A["Container A<br/>ping db"] --> B["Docker DNS<br/>127.0.0.11"]
    B -->|db → 172.18.0.2| C["Container B<br/>172.18.0.2"]

▶ Example: --network-alias to set an alias (Difficulty: ⭐⭐)

BASH
# Start container with network alias
docker run -d --name my-postgres \
  --network app-net \
  --network-alias=database \
  --network-alias=db \
  postgres:15-alpine

# Both names resolve to the same container
docker exec api ping -c 1 database  # resolves to my-postgres
docker exec api ping -c 1 db        # same IP

(1) Container Name vs. Network Alias

Type Definition Scope Priority
--name Container Name All Networks High
--network-alias Network Alias Specify Network Only Medium
Docker Compose service name Service name Compose network High
💡 Tip: --network-alias allows the same container to have different names in different networks. For example, the database is named primary-db in backend-net and database in admin-net.


6. Port Exposure Policy

(1) --expose vs -p vs -P

Parameter Function Externally Accessible Use Cases
--expose 3306 Port Declaration (Documentation) ❌ Not Mapped Inter-container Communication
-p 3306:3306 Mapped to host ✅ Accessible from outside External service
-P Randomly Map EXPOSE Ports ✅ Random Ports Development and Debugging

▶ Example: Use docker port to view port mappings (Difficulty: ⭐)

BASH
# Check port mappings for a container
docker port web

# Output example
80/tcp -> 0.0.0.0:8080

7. Network Troubleshooting

(1) Troubleshooting Decision Trees

100%
graph TB
    START["Container A<br/>cannot reach Container B"] --> DNS{"DNS Analysis?"}
    DNS -->|Failure| FIX1["The Same Custom Network?<br/>Using --name or --network-alias"]
    DNS -->|Success| PING{"Ping Through?"}
    PING -->|Failure| FIX2["On the Same Network?<br/>docker network connect"]
    PING -->|Success| PORT{"Port Connect?<br/>nc -zv B port"]
    PORT -->|Failure| FIX3["Port Exposure?<br/>B Is the correct port being listened to??"]
    PORT -->|Success| APP{"Application Protocol?<br/>curl/wget Test"]
    APP -->|Failure| FIX4["Check the app configuration<br/>Environment Variables/URL"]
    APP -->|Success| OK["✅ Communication is working properly"]

▶ Example: Commands for troubleshooting container networking (Difficulty: ⭐⭐)

BASH
# Step 1: Check DNS resolution
docker exec api nslookup db
docker exec api getent hosts db

# Step 2: Test basic connectivity
docker exec api ping -c 2 db

# Step 3: Test specific port
docker exec api nc -zv db 5432
# or with wget
docker exec api wget -qO- http://api:8080/health

# Step 4: Check container's network interfaces
docker exec api ip addr

# Step 5: Check routing table
docker exec api ip route

▶ Example: docker network connect to dynamically join a network (Difficulty: ⭐⭐)

BASH
# Connect a running container to another network
docker network connect backend-net web

# Disconnect from a network
docker network disconnect frontend-net web

# Verify container's networks
docker inspect web --format='{{json .NetworkSettings.Networks}}' | python3 -m json.tool

8. Security Group Isolation Design

(1) Three-Layer Isolation Model

Network Layer Container Accessible External Port
Frontend Net Nginx/CDN Backend Net only 80, 443
Backend Net API/Worker DB Net only None(Via Nginx Proxy)
DB Net PostgreSQL/Redis No external access None
🔒 Security: The database resides solely within DB Net; frontend containers cannot access the database directly—they must go through the backend API. This follows the "least privilege" principle.


9. Complete Example: Microservice Network Configuration and Troubleshooting

BASH
# ============================================
# Complete walkthrough: Microservice networking
# Covers: networks, aliases, isolation, debugging
# ============================================

# 1. Create isolated networks
docker network create frontend-net
docker network create backend-net
docker network create db-net

# 2. Start database (db-net only)
docker run -d --name postgres \
  --network db-net \
  --network-alias=database \
  --network-alias=primary-db \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=myapp \
  postgres:15-alpine

# 3. Start API server (backend-net + db-net)
docker run -d --name api \
  --network backend-net \
  --network-alias=api-server \
  -e DATABASE_URL="postgresql://postgres:secret@primary-db:5432/myapp" \
  myapp-api:1.0

docker network connect db-net api

# 4. Start Nginx (frontend-net + backend-net)
docker run -d --name nginx \
  --network frontend-net \
  --network-alias=gateway \
  -p 8080:80 \
  nginx:1.25-alpine

docker network connect backend-net nginx

# 5. Debug: verify connectivity
echo "=== DNS Resolution ==="
docker exec nginx nslookup api-server
docker exec api nslookup primary-db

echo "=== Port Connectivity ==="
docker exec nginx nc -zv api-server 5000
docker exec api nc -zv primary-db 5432

echo "=== Isolation Check ==="
docker exec nginx sh -c "timeout 2 nc -zv primary-db 5432 2>&1 || echo 'BLOCKED: nginx cannot reach db directly (expected)'"

# 6. Clean up
docker stop postgres api nginx
docker rm postgres api nginx
docker network rm frontend-net backend-net db-net

❓ FAQ

Q Has --link been deprecated?
A Yes. Docker has officially deprecated --link and recommends using custom networks + DNS instead. Issues with --link include: one-way connections, IP addresses not updating after a restart, and lack of support for Compose. Custom networks resolve all of these issues.
Q Are container names unique across different networks?
A Container names are globally unique on the Docker host. However, DNS resolution occurs at the network level—only containers on the same network can resolve each other by container name. To resolve across networks, you must first add docker network connect.
Q How can I ensure that a container can only be accessed by specific containers?
A Use network isolation. Place the service you want to protect (such as a database) in a dedicated network, and only add containers that need to access it to that network. For example, if the database is in db-net, only the API is added to db-net, so Nginx cannot directly access the database.
Q What should I do if a container experiences a DNS timeout?
A DNS timeouts are usually caused by: ① The container is not on the same network (most common); ② A typo in the container name; ③ DNS cache issues (restarting the container resolves this). Troubleshooting: docker exec <container> nslookup <target> Check the resolution results.
Q How do I view the container’s actual IP address?
A docker inspect <container> --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'. Or enter the container and run ip addr / hostname -I. But remember: the IP address may change, so use the container name instead of the IP address in production code.

📖 Summary


📝 Exercises

  1. Basic Exercise (Difficulty: ⭐): Create two custom networks, start one container on each, and verify that DNS resolution for container names within the same network works properly.
  2. Advanced Exercise (Difficulty ⭐⭐): Verify that containers across networks cannot ping each other, then establish a connection using docker network connect, and then disconnect.
  3. Challenge Question (Difficulty: ⭐⭐⭐): Use docker exec + nc / wget to troubleshoot the root cause of one container being unable to access another container’s service. Describe the troubleshooting steps and draw a conclusion.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏