DNS and Service Discovery
In one sentence: On user-defined networks the engine runs an embedded DNS server inside each sandbox's view (at 127.0.0.11), resolving container names to current container IPs — so apps say db and never hardcode an address.
You already know
- From Lesson 28: networks allocate IPs dynamically — an IP can change on every recreate.
- From Lesson 13: the engine already has a name→resource store; DNS is the same idea for the network.
Names as the stable interface
Dynamic IPs are only a problem if anything remembers them. The fix: make the engine the authority for names. Each sandbox's /etc/resolv.conf points at 127.0.0.11 — an address the engine intercepts and serves itself, backed by its live container tables. Resolution is scoped: a lookup for db answers only if a container named db (or carrying that network alias) shares a network with the asker — the same segmentation from Lesson 28, extended to names. Anything unknown (like example.com) is forwarded to real upstream DNS. Because answers come from live state, recreating db with a new IP updates the answer instantly; nothing anywhere holds a stale address.
flowchart LR APP["app in sandbox
resolv.conf → 127.0.0.11"] --> EDNS["embedded DNS
(engine-served)"] EDNS -- "name on a shared network?" --> TBL[("engine's live tables
db → 172.19.0.3")] EDNS -- "unknown name" --> UP["upstream DNS
(host's resolvers)"] TBL --> A1["answer: container IP"] UP --> A2["answer: internet IP"]
sequenceDiagram
participant A as app (in web's sandbox)
participant D as embedded DNS (127.0.0.11)
participant T as engine tables
participant U as upstream DNS
A->>D: resolve "db"
D->>T: container "db" on a network shared with web?
T-->>D: yes — 172.19.0.3
D-->>A: 172.19.0.3 (fresh from live state)
A->>D: resolve "api.stripe.com"
D->>U: forward
U-->>D: 54.187.x.x
D-->>A: 54.187.x.x
Anchor these
- Container names are the stable interface; IPs are disposable implementation detail.
- Resolution is network-scoped — names leak exactly as far as connectivity does.
- Unknown names forward upstream; the embedded server is authority + relay.
See what actually stuck.
Take the practice scenarios now.