Skip to main content

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

  1. 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
  1. 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
  1. 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.