Skip to content
Optimal Lab

DevOps · interactive

Container networking

Each container has its own network namespace, its own localhost and its own IP on a Docker network. Containers on the same user-defined network find each other by name; the host only sees ports you publish.

Your laptop (host)

docker network: app (172.18.0.0/16)

web

172.18.0.2

-p 8080:80

api

172.18.0.3

not published

db

172.18.0.4

not published

api → localhost:5432: connection refused

Inside a container, localhost is that container. There's no Postgres in api, so: connection refused.

Connection

Step 1 of 4

  1. 1

    localhost means this container

    The most common mistake: an app in a container connecting to localhost for a database in another container.

    Use the service name instead.

  2. 2

    Names resolve on user networks

    Docker's embedded DNS (and Compose service names) map container names to IPs, which change on restart.

    DATABASE_URL=postgres://db:5432/app

  3. 3

    Publish only what users need

    -p host:container opens a port on the host. Keep databases unpublished in production.

    -p 127.0.0.1:5432:5432 limits it to your machine.

  4. 4

    Same idea, bigger

    In Kubernetes, containers in a pod share localhost, pods talk via Service names, and Ingress publishes to the outside.

    See Services and Ingress.

In production

Tools and technologies

Docker and Compose networking is where most local setups break.

Not tied to one language — use these names when you search docs or design a system.