Skip to content

Docker Networking Explained

Docker networking lets containers talk to each other and to the outside world.

Network Types

NetworkIsolationUse Case
Bridge (default)Per-containerSingle-host communication
HostNonePerformance-critical apps
OverlayAcross hostsDocker Swarm, multi-host
NoneFull isolationSecurity-sensitive tasks
MacvlanMAC-per-containerLegacy network apps

Bridge Network (Default)

When you install Docker, a default bridge network is created:

# List networks
docker network ls

# Inspect default bridge
docker network inspect bridge

Containers on the same bridge network can communicate by IP:

docker run -d --name container1 nginx
docker run -it --name container2 alpine ping <container1-ip>

User-Defined Bridge

Better than the default bridge — provides DNS resolution by container name:

# Create a custom network
docker network create my-network

# Connect containers
docker run -d --name api --network my-network my-api:latest
docker run -d --name db --network my-network postgres:16

# api can reach db by name: ping db (not an IP!)
docker exec api ping db

This is the recommended approach for Docker Compose and multi-container apps.

Exposing Ports

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

# Map random host port to container port 80
docker run -d -p 80 nginx

# UDP port
docker run -d -p 53:53/udp dns-server

Host Network

The container shares the host’s network stack — no isolation:

docker run --network host nginx

Best for: performance-critical apps where network overhead matters. Worst for: security (no isolation).

Connecting a Running Container

# Add container to a network
docker network connect my-network my-container

# Remove from a network
docker network disconnect my-network my-container

Inspecting Containers

# Network details of a container
docker inspect <container-id> | grep -A 20 "Networks"

# Or format it nicely
docker inspect --format='{{json .NetworkSettings}}' <container-id>

# List IP addresses
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container-name

Internal vs External Communication

┌─────────────────────────────────┐
│         Host Machine            │
│  ┌─────────────┐ ┌───────────┐  │
│  │ Container A │ │Container B │  │
│  │  app:8000   │ │ db:5432   │  │
│  └──────┬──────┘ └───────────┘  │
│         │ bridge network        │
│  ┌──────┴──────┐                │
│  │   Host      │                │
│  │  localhost  │                │
│  │  :8000      │                │
│  └─────────────┘                │
└─────────────────────────────────┘
  • Containers reach each other by name or IP on the same network
  • The outside world reaches containers through published ports
  • Host reaches containers via localhost:published-port

Docker Compose Networking

Compose automatically creates a network for your project:

services:
  api:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend
  nginx:
    networks:
      - frontend

networks:
  frontend:
  backend:

All services on the same network can reach each other by service name.

Common Problems

Container can’t reach another by name

# Check they're on the same network
docker inspect container-a --format='{{json .NetworkSettings.Networks}}'
docker inspect container-b --format='{{json .NetworkSettings.Networks}}'

Can’t connect to container from host

# Make sure port is published
docker run -d -p 8080:80 nginx       # ✓ published
docker run -d nginx                  # ✗ not published

Port already in use

docker ps | grep 8080        # find what's using it
docker stop <container-id>   # stop it

DNS not resolving

# Use IP instead (temporary)
docker inspect container-name | grep IPAddress

# Or check DNS settings
docker run --dns 8.8.8.8 alpine ping google.com

Related: Learn Docker Compose and Docker for beginners.