Command Palette

Search for a command to run...

Hectal
PHASE 4Intermediate ~13 min· topic 3 of 3

Topic 4.3

DNS & Service Discovery Between Containers

In one line

On a user-defined network, Docker gives you automatic, name-based service discovery for free — understanding exactly how it works removes a huge amount of Docker Compose 'magic' later.

0/3 · 0%

Key ideas

  1. 01

    Every container on a user-defined bridge network is automatically registered with Docker's built-in embedded DNS server, mapping its container NAME (and any --network-alias) to its current internal IP address — no manual configuration required.

  2. 02

    This means one container can reach another using its NAME as if it were a real hostname — http://db:5432, http://redis:6379, http://api:8080 — Docker's embedded DNS resolves these names transparently, exactly like a real DNS server would for a domain name.

  3. 03

    This is critical because a container's internal IP address is NOT stable — it can change if the container is recreated. Hardcoding an IP address in your app's configuration would break the moment that container restarts and gets reassigned a different IP; using the container's NAME instead means it keeps working regardless of IP changes underneath.

  4. 04

    --network-alias lets a container respond to MULTIPLE names on the network — useful when you want to refer to the same container by different names from different consuming services, or when swapping which actual container answers to a given alias (a lightweight blue/green-style trick).

  5. 05

    Docker Compose (Phase 5) builds directly on this mechanism: every service defined in a docker-compose.yml file automatically gets a DNS name equal to its SERVICE NAME, on a network Compose creates for you automatically — this is exactly why a Compose-defined Spring Boot service's config can simply say jdbc:postgresql://db:5432/mydb with zero manual network setup.

  6. 06

    This DNS resolution is SCOPED to one specific network — a container only resolves the names of OTHER containers that are attached to the SAME network as it. A container on network A cannot resolve a container's name that's only attached to network B, even if both are running on the same Docker host.

In your stack

  • →

    This is precisely why a Spring Boot application.properties in a containerized setup writes spring.datasource.url=jdbc:postgresql://db:5432/mydb instead of a hardcoded IP address — db is resolved fresh by Docker's DNS every time, so the config keeps working correctly even after the database container restarts and receives a new internal IP.

Code & diagrams

network-aliases.shmarkdown

One container, answering to two different names.

docker network create mynetwork

# This container responds to BOTH "cache" and "redis-primary" on the network
docker run -d --name cache-container \
  --network mynetwork \
  --network-alias cache \
  --network-alias redis-primary \
  redis:7-alpine

docker run -it --rm --network mynetwork alpine sh -c \
  "apk add --no-cache bind-tools && nslookup cache && nslookup redis-primary"
# Both should resolve to the SAME internal IP — the one container's address

Explain it without notes

01

Why is hardcoding a container's internal IP address into another container's config a fragile choice, even though it might work fine the moment you first set it up?

02

Two containers are both running, but one can't resolve the other's name via DNS. What's the single most likely cause, given everything in this phase so far?

Practice

01

Reproduce the network-alias exercise and confirm both names resolve to the identical IP.

02

Create TWO separate user-defined networks, put one container on each, and confirm they CANNOT resolve each other by name — then attach both to the same third network and confirm resolution now works.

Trade-offs

  • ↔

    Relying on container-name DNS resolution requires everything to be on a shared user-defined network, which is a small amount of upfront setup — but the alternative (hardcoded IPs, or manual /etc/hosts-style entries) is strictly worse and more fragile in every practical sense.

Done when you can

  • I never hardcode a container's internal IP address in another container's configuration.

  • I understand that DNS resolution is scoped per-network, not global across the whole Docker host.

  • I can use --network-alias to give a container an additional resolvable name.