Docker Networking Basics
Container networking lets your containers discover and communicate with each other safely and predictably. This page shows the essential Docker networking concepts and gives copy-pasteable examples so you can connect containers for local development or a simple production stack.
Concept explained
- Default bridge network: Docker places containers on a default bridge; name-based DNS and isolation are limited.
- User-defined bridge networks: Recommended for most apps – provide automatic DNS (container name resolution), isolation, and easier port exposure control.
- network inspect: view connected containers and config.
- docker-compose networks: Compose creates and wires networks for services automatically; use service names as hostnames.
- Special drivers:
- host: bypasses networking stack (not recommended unless needed).
- none: container has no network.
- overlay: for multi-host Swarm/Kubernetes (outside this guide).
tip
On user-defined bridge networks, containers can reach each other by service/container name without publishing ports to the host.
Step-by-step example
- Create a user-defined network and run two containers that talk to each other.
# create network
docker network create web-net
# run a backend DB container
docker run -d --name mydb --network web-net postgres:15 -e POSTGRES_PASSWORD=example
# run a simple client container and check DB connectivity by name
docker run --rm --network web-net postgres:15 pg_isready -h mydb -U postgres
- Example with an application container that connects to a DB using environment vars:
docker run -d \
--name api \
--network web-net \
-e DATABASE_HOST=mydb \
-e DATABASE_PORT=5432 \
myorg/myapp:latest
- Compose example (recommended for multi-service projects):
services:
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- db-data:/var/lib/postgresql/data
api:
image: myorg/myapp:latest
environment:
DATABASE_HOST: db
DATABASE_PORT: "5432"
depends_on:
- db
ports:
- "8080:8080"
volumes:
db-data:
# by default, Compose creates a project network and services can use 'db' as hostname
Check connectivity and network details:
docker network inspect web-net
docker ps --format "{{.Names}}\t{{.Ports}}"
docker logs api
Variations & gotchas
- docker network connect: attach an existing container to another network.
docker network connect web-net existing-container
- DNS resolution uses container names; if you need custom names, use aliases in compose:
services:
db:
...
networks:
default:
aliases:
- primary-db
- host network: on macOS/Windows it behaves differently (Docker Desktop). Use with care – not isolated.
- overlay networks require Swarm/Kubernetes; they won't work for single-host Docker without orchestrator.
caution
Don't assume published ports (docker run -p) are needed for container-to-container traffic. Publishing exposes services to the host and internet; inter-container DNS on the same network bypasses host ports.
Common mistakes
- Relying on the default bridge network for multi-service apps – you lose automatic DNS and tighter isolation.
- Naming collisions: reusing container names across projects connected to the same network can cause confusion. Prefer per-project networks.
- Expecting cross-host connectivity without an overlay/cluster driver – bridge networks are host-local.
- Not inspecting network connections when a service can't reach another – use docker network inspect and logs.
Best practices
- Create a user-defined bridge per project (or let Compose create one). It gives DNS and isolation.
- Use service names as hostnames; use short aliases when needed.
- Avoid --network host unless you need host networking semantics (performance, special protocols).
- Keep networks per environment (dev/staging/prod) to avoid accidental cross-talk.
- Use compose's depends_on for start order but rely on health checks or retries in apps for robust startup.
When to use / when not to use
-
Use user-defined bridge networks when:
- Running multiple services on the same host.
- You want simple service discovery via names.
- You want predictable isolation per project.
-
Don't use user-defined bridge networks when:
- You need cross-host networking (use overlay or orchestrator).
- You require host network performance or access to host interfaces (use host carefully).
Key takeaways
- Create a user-defined bridge network for predictable DNS and isolation.
- Containers on the same user network can reach each other by name without published ports.
- Use docker-compose for multi-service apps – Compose handles networks for you.
- Inspect networks and logs when connectivity fails: docker network inspect, docker logs.