Networking

Docker networking controls how containers talk to each other, the host, and the outside world. Most application problems show up as one of three symptoms: DNS does not resolve, a port is not published, or traffic is going to the wrong network.

Default rule

Use a user-defined bridge network for local multi-container applications. Containers on the same user-defined bridge network can resolve each other by service or container name.

1docker network create appnet
2docker run -d --name db --network appnet mysql:latest
3docker run --rm --network appnet alpine:latest getent hosts db

Compose creates a project network automatically, so services can usually talk to each other by service name.

1services:
2  api:
3    image: api:local
4    depends_on:
5      - db
6  db:
7    image: mysql:latest

The api container connects to the database host named db.

Published ports

Publishing a port makes a container port reachable from the host.

1docker run --rm -p 8080:80 nginx:alpine

The left side is the host port. The right side is the container port. In the example, open http://localhost:8080 on the host.

Compose uses the same mapping.

1services:
2  web:
3    image: nginx:alpine
4    ports:
5      - "8080:80"

Expose versus publish

EXPOSE in a Dockerfile is documentation and metadata. It does not publish the port to the host. Use -p or Compose ports when the host must connect to the container.

Host access

Containers can reach the host differently depending on the platform.

  • Docker Desktop provides host.docker.internal.

  • Linux Docker Engine can add the host gateway explicitly.

1docker run --rm \
2    --add-host=host.docker.internal:host-gateway \
3    alpine:latest ping -c 1 host.docker.internal

Use host access sparingly. A containerized dependency is usually easier to reproduce than a dependency running directly on a developer laptop.

Host network mode

Host network mode removes Docker’s network namespace isolation for that container.

1docker run --rm --network host nginx:alpine

This can be useful for diagnostics or high-performance network appliances on Linux. It is not the default application pattern because it bypasses normal port publishing and increases coupling to the host.

Internal networks

Use internal networks for services that should not be reachable from outside the Compose project.

 1services:
 2  api:
 3    image: api:local
 4    networks:
 5      - frontend
 6      - backend
 7  db:
 8    image: mysql:latest
 9    networks:
10      - backend
11
12networks:
13  frontend:
14  backend:
15    internal: true

Debugging

Start with these commands.

1docker network ls
2docker network inspect appnet
3docker container inspect api
4docker port api
5docker exec -it api sh

Inside a debugging shell, check DNS and ports.

1getent hosts db
2nc -vz db 3306
3wget -S -O - http://api:8080/health

Practical rules

  • Use user-defined bridge networks.

  • Connect containers by DNS name, not by container IP address.

  • Publish only the ports that humans or external systems need.

  • Do not use host network mode unless the workload truly needs it.

  • Separate frontend and backend networks when the topology matters.

  • Debug from inside a container on the same network.

References