Docker DNS, Service Discovery, Aliases, IPv4/IPv6, Custom Subnets, and Multi-Network Applications: Configuration, Design Choices, and Tradeoffs
Choose deliberately among service names, aliases, static addresses, multiple networks, external DNS boundaries, IPv4-only, and dual-stack Docker designs.
Learning objectives
- Choose service names, aliases, or external DNS based on ownership and network scope instead of convenience alone.
- Prefer dynamic endpoint addressing while recognizing narrow cases where static IPv4/IPv6 addresses are justified.
- Decide when a service should be single-homed or multi-homed and explain the resulting blast-radius and routing implications.
- Compare IPv4-only and dual-stack designs without assuming address allocation equals end-to-end reachability.
- Use normalized Compose/Docker network evidence to justify each design choice and its operational prerequisites.
1. Service name versus network alias
Use the Compose service name when consumers mean “this service.” It is the simplest discovery contract and survives container recreation. Use an alias when consumers need a network-specific compatibility name, a migration name, or a role that should exist only on one attachment.
| Choice | Strength | Risk | Evidence to retain |
|---|---|---|---|
| Service name | Simple, canonical, project-local discovery | Renaming the service is a contract change | Normalized Compose model + successful lookup |
| Network alias | Different names on different networks; compatibility/migration | Alias collision can make resolution ambiguous | Network attachment aliases + lookup from each scope |
| Container name | Useful in direct CLI labs | Couples clients to one container object/scaling model | Container ID/name + network membership |
| External DNS name | Works across hosts/platform boundaries | Requires external DNS ownership, routing and TLS policy | DNS record/TTL + endpoint ownership + application identity |
2. Dynamic addressing versus static addressing
Dynamic Docker IPAM is the default because it decouples service identity from endpoint allocation. Static addresses add coordination and collision risk; they can be appropriate when integrating with an appliance, allowlist, legacy license system, routing policy, or protocol that genuinely requires an address.
If Compose uses ipv4_address or
ipv6_address, the top-level network IPAM configuration
must define a subnet that contains the requested address. Record why
the static address exists, who owns the subnet, and how collisions
are prevented.
services:
legacy-adapter:
image: example/adapter@sha256:<recorded-digest>
networks:
legacy:
ipv4_address: 172.30.50.10
networks:
legacy:
ipam:
config:
- subnet: 172.30.50.0/24
This is a design example, not a recommendation to copy that subnet. Check real routes and Docker networks first.
3. One network versus multiple networks
Single-homed services are easier to reason about and reduce reachability. Multi-homing is justified for a gateway/API that intentionally connects trust zones, but it also turns that container into a path between domains at the application level. Docker does not automatically make the application a router, yet the process can initiate connections on every attached network.
| Pattern | Use when | Security/reliability effect |
|---|---|---|
| One app network | All peers share one trust boundary | Simplest; broadest lateral reach among members. |
| Front + back networks | Only an API/gateway needs both zones | Reduces direct front-to-data reach; API becomes a critical boundary. |
| Dedicated network per dependency class | Strong segmentation is required | More explicit and auditable, but more config/diagnostic complexity. |
| Attach everything everywhere | Rarely justified | Erodes isolation and makes DNS/route failures harder to localize. |
4. Docker-managed DNS versus external DNS
Docker embedded DNS is appropriate for peers on the same custom Docker network. External DNS begins where the Docker daemon no longer owns the destination identity: a database on another host, a SaaS API, a corporate service, or a multi-host platform. Embedded DNS forwards non-Docker lookups, but it does not become authoritative for your organization’s zones.
Keep trust separate from resolution. A DNS answer says “this name maps to this address,” not “this server is authorized.” TLS certificate verification, application authentication, authorization, and signature/trust policy remain separate layers.
5. IPv4-only versus dual-stack
| Design | Advantages | Costs / prerequisites | Verification |
|---|---|---|---|
| IPv4-only | Broad compatibility; simplest local labs | NAT/address pressure; not an IPv6 readiness test | IPv4 endpoint + route + DNS + app test |
| Dual-stack | Exercises both protocol families; migration flexibility | Host/daemon/upstream IPv6 policy, application dual-stack behavior, DNS AAAA decisions | Separate IPv4 and IPv6 endpoint/routes/connect tests |
| IPv6-only custom network | Useful for specialized testing | Application/tool support and external dependencies may assume IPv4 | Resolver + IPv6 endpoint + route + application behavior |
Docker's embedded DNS still uses the IPv4 resolver address
127.0.0.11, including in IPv6-only containers according
to current Docker documentation. Do not misread that resolver
address as evidence that the workload network itself is IPv4-only.
6. Custom IPAM: choose ranges as infrastructure, not decoration
A subnet is part of routing architecture. Before creating it, compare against host routes, VPN routes, cloud/VPC ranges, other Docker networks, and peer networks. Overlap can create traffic ambiguity long before DNS is involved. For Compose, keep IPAM in source control when the range is intentional, but avoid hard-coded static service IPs unless required.
# Read-only checks before choosing a range:
docker network ls -q | xargs -r docker network inspect \
--format '{{.Name}} {{json .IPAM.Config}}'
ip route 2>/dev/null || true
# Render Compose intent before execution:
docker compose -f compose.yaml config
7. Worked Compose design: front/back segmentation
name: da18-design
services:
frontend:
image: busybox:1.36.1
command: ["sh", "-c", "sleep 3600"]
networks: [front]
api:
image: busybox:1.36.1
command: ["sh", "-c", "sleep 3600"]
networks:
front:
aliases: [api]
back:
aliases: [api-internal]
database:
image: busybox:1.36.1
command: ["sh", "-c", "sleep 3600"]
networks:
back:
aliases: [data]
networks:
front: {}
back:
internal: true
The internal: true back network is an additional
egress/isolation property, not a replacement for service-level
authentication. The key architectural property is membership:
frontend has no back endpoint, while
api deliberately has both.
8. Decision table
| Question | Default | Choose differently when… | Observable proof |
|---|---|---|---|
| Name or alias? | Service name | Compatibility/migration/network-specific role needs an alternate name | Network alias list + scoped lookup |
| Dynamic or static IP? | Dynamic | External integration requires allowlisted/stable address | IPAM subnet + static assignment + ownership note |
| One or multiple networks? | Minimum memberships | Service intentionally bridges application trust zones |
NetworkSettings.Networks + connectivity matrix
|
| Docker DNS or external DNS? | Docker DNS for same-network peers | Destination is outside daemon-owned discovery | Resolver trace + authoritative external DNS evidence |
| IPv4 or dual-stack? | IPv4 for baseline | Product/network has an explicit IPv6 requirement | Per-family address/route/DNS/application tests |
9. Keep adjacent states separate
- Network membership ≠ DNS success. An alias may be absent or misspelled.
- DNS success ≠ application reachability. The service can be stopped or listening on another interface/port.
- Container IP ≠ host-published address. Port publication is a separate Chapter 19 path.
- IPv6 endpoint ≠ IPv6 Internet route. Host/upstream policy still governs external traffic.
- Resolution ≠ trust. TLS/authentication/authorization still apply.
10. Scenario: justify the API as the only dual-homed service
Suppose a web tier needs read/write access to an API, and only that
API needs the database. A front/back network design makes the policy
visible: the web tier can resolve api; the API can
resolve data; the web tier cannot resolve
data. The evidence packet includes the normalized
Compose model, network IDs/IPAM, API's two endpoints, alias sets,
and three lookup/connection results.
If an engineer proposes attaching the web tier to the back network “because DNS is easier,” the operational cost is a larger blast radius and a weaker architecture. The correct fix to a missing path depends on intended policy, not on making every lookup succeed.
Knowledge check
When is a network alias preferable to renaming the service?
When consumers need a compatibility or network-specific name while the canonical service identity should remain unchanged.
What is the default choice for container addressing?
Dynamic IPAM plus stable names/aliases. Static addresses should have a documented external requirement and a managed non-overlapping subnet.
Why is a dual-homed API security-relevant?
It can initiate application connections into both network zones, so it becomes a deliberate trust boundary even though Docker does not automatically route arbitrary packets through it.
Does successful external DNS resolution prove TLS identity?
No. Resolution and trust are separate; certificate/authentication/authorization evidence is still required.
What must be verified separately in a dual-stack design?
IPv4 and IPv6 endpoint allocation, routes, DNS behavior/records, application binding, and actual connections for each protocol family.
Official references and version notes
-
Docker Docs — Networking overview
— resolver behavior, custom-network embedded DNS, and
127.0.0.11. - Docker Docs — Bridge network driver — user-defined bridge isolation and automatic name/alias resolution.
- Docker Docs — docker network connect — endpoint attachment and network-scoped aliases.
- Docker Docs — Networking in Compose — project networks and service-name discovery.
- Compose Specification — service network aliases — aliases are scoped to the network on which they are declared.
-
Compose Specification — networks
— IPAM,
enable_ipv4,enable_ipv6, internal/external networks, and custom names. - Docker Docs — IPv6 networking — Linux-daemon support, IPv6 network creation, ULA allocation, and Compose examples.
- Docker Engine 29 release notes — current Engine behavior and networking fixes.
Docker Engine 29.8.1 (released 2026-09-15) is the current Engine 29 release in the primary release notes, and Docker Compose v5.5.1 is the current upstream Compose release. The runnable labs deliberately record your Engine/CLI/Compose versions and context because DNS, IPv6, Desktop networking, firewall integration, and helper-tool availability vary by platform. The mandatory path uses only local disposable networks and containers; IPv6 is an optional capability-gated extension.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.