📝 Docker

Docker Networking: How Containers Communicate

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
3 min
👁️
Views
82
🌳
Level
Advanced

Containers are isolated, but they often need to talk to each other and to the outside world. Docker handles this through network drivers.

Network Drivers

Docker supports several network types:

Driver Description
bridge Virtual network on the host. Default for all containers
host Container shares the host’s network stack directly
none No network. Complete isolation
overlay For Swarm: network spanning multiple hosts
docker network ls                        # list networks
docker network inspect bridge            # network details
docker network create my-network         # create a network
docker network rm my-network             # remove a network

Default Bridge: Containers Communicate by IP

By default every container is attached to the bridge network. Containers can reach each other only by IP address.

# Start two containers
docker run -d --name app1 alpine sleep infinity
docker run -d --name app2 alpine sleep infinity

# Get the IP of the first container
docker inspect app1 | grep IPAddress
# → 172.17.0.2

# Ping app1 from app2 using its IP
docker exec app2 ping 172.17.0.2

The problem: the IP changes on restart. The solution is a user-defined network.

User-Defined Network: DNS by Container Name

In a user-defined network, Docker automatically registers DNS entries using the container name. Containers can reach each other by name.

# Create a network
docker network create my-app-net

# Start containers on this network
docker run -d --name postgres --network my-app-net postgres:15
docker run -d --name web --network my-app-net my-web-app

# From web, connect to postgres by name:
# postgresql://postgres:5432/db

The container name becomes a reliable address. DNS works automatically.

How Docker Compose Creates a Network

Docker Compose automatically creates a dedicated network for each project. All services in docker-compose.yml are connected to it and can reach each other by service name.

services:
  web:
    build: .
    # Can reach "db" and "redis" by name

  db:
    image: postgres:15

  redis:
    image: redis:7

The network is named <project-folder>_default. No extra configuration needed.

To isolate services from each other, declare multiple networks explicitly:

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend          # db is unreachable from the frontend network

networks:
  frontend:
  backend:

Port Mapping: -p HOST:CONTAINER

A container is not reachable from outside by default. The -p flag maps a host port to a container port.

# Syntax: -p HOST:CONTAINER
docker run -p 8080:80 nginx            # localhost:8080 → container:80
docker run -p 127.0.0.1:8080:80 nginx  # localhost only
docker run -p 5432:5432 postgres       # postgres reachable from host

# Multiple ports
docker run -p 80:80 -p 443:443 nginx

# Random host port
docker run -p 80 nginx                 # Docker picks the port
docker port <container>                # find out which port was assigned

In docker-compose.yml:

ports:
  - "8080:80"                    # host:container
  - "127.0.0.1:5432:5432"        # localhost only

Example: nginx + app + postgres

A full stack with separate networks for isolation:

version: "3.8"

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - frontend
    depends_on:
      - app

  app:
    build: .
    environment:
      DATABASE_URL: postgresql://user:pass@postgres:5432/mydb
    networks:
      - frontend
      - backend
    depends_on:
      - postgres

  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - backend       # postgres is not visible from nginx

volumes:
  pgdata:

networks:
  frontend:
  backend:

nginx configuration for proxying to app:

server {
    listen 80;
    location / {
        proxy_pass http://app:8000;
    }
}

nginx reaches app by service name. app reaches postgres by service name. postgres is isolated in the backend network and is not accessible from the internet.

Useful Diagnostic Commands

# List all networks
docker network ls

# What is connected to a network
docker network inspect my-app-net

# IP addresses of a container
docker inspect web | grep -A 20 '"Networks"'

# Check connectivity between containers
docker exec app ping db
docker exec app curl http://nginx/health

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Deploying FastAPI with Docker

Railway will also automatically detect a Dockerfile if one is present.

📅 30.06.2026 👁️ 83
📝

Multi-stage Builds: Shrinking Your Docker Image

A large image means slow downloads, more disk usage, and a bigger attack surface. Multi-stage...

📅 30.06.2026 👁️ 79
📝

Docker Compose: Advanced Features

A basic docker-compose.yml is just the starting point. Production workloads need healthchecks, profiles, override files,...

📅 30.06.2026 👁️ 79

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!