Docker Networking Single Host
Learn Docker, Containerization, Docker Compose, Docker Swarm - Part 011
Docker networking single-host: bridge, host, none, macvlan, ipvlan, DNS, port publishing, localhost trap, service discovery, firewall/NAT, troubleshooting, dan network failure modeling.
Part 011 — Docker Networking: Bridge, Host, None, Macvlan, DNS, and Ports
1. Tujuan Part Ini
Part sebelumnya membahas resource management: CPU, memory, IO, PID, OOM, dan backpressure. Sekarang kita masuk ke salah satu boundary container yang paling sering disalahpahami: networking.
Docker networking sering terlihat sederhana karena command seperti ini tampak mudah:
docker run -p 8080:8080 my-api
Tetapi di balik satu flag itu ada beberapa konsep:
- network namespace;
- virtual Ethernet pair;
- Linux bridge;
- NAT;
- iptables/nftables rules;
- port publishing;
- embedded DNS;
- hostname dan container name;
- host interface binding;
- route table;
- service discovery;
- resolver behavior;
- firewall interaction;
- Docker Desktop VM boundary.
Target setelah part ini:
- memahami container networking sebagai kombinasi namespace + virtual interface + routing + DNS + port mapping;
- bisa membedakan
bridge,host,none,macvlan, danipvlan; - memahami default bridge vs user-defined bridge;
- memahami kenapa
localhostsering salah dipakai; - bisa mendesain network Compose dengan service discovery yang bersih;
- bisa membaca network topology dari
docker network inspect; - bisa debug connectivity menggunakan layer-by-layer method;
- bisa mengenali failure mode: DNS stale, port conflict, bind address salah, hairpin NAT, firewall, MTU, proxy, IPv6, dan container-to-host access;
- bisa membuat network contract untuk aplikasi multi-service.
Inti part ini: container networking bukan magic. Container adalah process dengan network namespace sendiri. Docker menghubungkan namespace itu ke host dan container lain melalui driver network, DNS, NAT, dan routing policy.
2. Kaufman Deconstruction: Subskill Networking yang Harus Dikuasai
Agar belajar efektif, jangan mulai dari menghafal semua driver. Pecah skill Docker networking menjadi subskill kecil:
| Subskill | Pertanyaan yang Harus Bisa Dijawab | Bukti Penguasaan |
|---|---|---|
| Namespace model | Container melihat network stack yang mana? | Bisa menjelaskan IP, interface, route dari dalam container |
| Driver selection | Kapan pakai bridge, host, none, macvlan? | Bisa memilih driver berdasarkan constraint, bukan kebiasaan |
| Port publishing | Apa beda container port, host port, exposed port? | Bisa memprediksi request masuk akan sampai ke process mana |
| Service discovery | Bagaimana container menemukan container lain? | Bisa menggunakan service name, network alias, dan DNS dengan benar |
| Localhost semantics | localhost menunjuk ke siapa? | Tidak salah menghubungkan app container ke DB host/container |
| Debug flow | Di layer mana koneksi gagal? | Bisa debug dari process, port, DNS, route, firewall, NAT |
| Security boundary | Network mana yang boleh saling bicara? | Bisa memisahkan frontend/backend/admin network |
| Production boundary | Apa yang berubah di Swarm/Kubernetes? | Bisa menjelaskan bridge single-host vs overlay multi-host |
Skill goal untuk part ini bukan “tahu semua flag”, tetapi bisa menggambar traffic path.
3. Mental Model: Container Memiliki Network Stack Sendiri
Secara default, container tidak memakai network namespace host. Ia memiliki network stack sendiri:
- interface sendiri, misalnya
eth0; - IP address sendiri;
- route table sendiri;
- DNS resolver config sendiri;
- port binding sendiri di namespace-nya;
- loopback sendiri (
127.0.0.1).
Diagram:
Konsekuensi penting:
localhostdi container berarti container itu sendiri, bukan host;- port
8080di container tidak otomatis terlihat dari host; - dua container di network yang sama bisa komunikasi lewat IP atau DNS name;
- port publishing diperlukan untuk traffic dari luar host menuju container;
- user-defined bridge memberikan DNS service discovery yang lebih baik daripada default bridge lama;
- network boundary adalah bagian dari security design.
4. Docker Network Object Model
Docker memiliki object bernama network. Container dapat di-attach ke satu atau lebih network.
Command dasar:
docker network ls
docker network inspect bridge
docker network create app-net
docker network rm app-net
Object network berisi:
- driver;
- subnet;
- gateway;
- IPAM config;
- connected containers;
- aliases;
- labels;
- options driver;
- internal/external flag;
- scope (
localatauswarm).
Contoh inspect:
docker network inspect app-net
Yang perlu dibaca:
{
"Name": "app-net",
"Driver": "bridge",
"Scope": "local",
"IPAM": {
"Config": [
{
"Subnet": "172.20.0.0/16",
"Gateway": "172.20.0.1"
}
]
},
"Containers": {
"...": {
"Name": "api",
"IPv4Address": "172.20.0.2/16"
}
}
}
Mental model:
Container bukan “berada di Docker” secara abstrak. Ia memiliki endpoint pada network tertentu.
5. Network Driver Overview
Docker Engine menyediakan beberapa network driver umum:
| Driver | Scope Umum | Kapan Digunakan | Risiko / Trade-off |
|---|---|---|---|
bridge | Single-host | Default untuk container biasa dan Compose lokal | NAT/port publishing perlu dipahami |
host | Single-host | Performance/low-latency, service yang butuh host network langsung | Menghilangkan network isolation |
none | Single-host | Job yang tidak boleh network access | Tidak ada external connectivity |
overlay | Multi-host Swarm | Service antar-node di Swarm | Dibahas detail di Part 027 |
macvlan | LAN-like | Container perlu tampak seperti device fisik di network | Network ops lebih kompleks; host-container comm punya nuance |
ipvlan | VLAN/L3 integration | Integrasi network enterprise/segmented | Butuh pemahaman routing/VLAN lebih matang |
Untuk single-host, mayoritas kasus production/development memakai user-defined bridge.
6. Bridge Network: Default Workhorse
Bridge network menggunakan software bridge di host. Container yang terhubung ke bridge yang sama dapat saling berkomunikasi, sementara container di bridge berbeda terisolasi kecuali ada port publishing atau routing tambahan.
6.1 Default Bridge vs User-Defined Bridge
Docker punya network bawaan bernama bridge. Tetapi untuk aplikasi nyata, lebih baik membuat user-defined bridge:
docker network create app-net
docker run -d --name db --network app-net postgres:16
docker run -d --name api --network app-net my-api:1.0
Kenapa user-defined bridge lebih baik?
| Aspek | Default bridge | User-defined bridge |
|---|---|---|
| DNS by container name | Terbatas/legacy behavior | Ya, automatic service discovery |
| Isolation antar aplikasi | Lemah jika semua memakai default bridge | Lebih bersih per app/project |
| Attach/detach container | Kurang fleksibel | Bisa connect/disconnect live |
| Config subnet/options | Global default | Per network |
| Operational clarity | Semua bercampur | Network per aplikasi |
Prinsip: jangan pakai default bridge untuk aplikasi multi-container yang serius. Buat network eksplisit.
6.2 Bridge Traffic Path: Container ke Container
Jika api memanggil db pada network yang sama:
docker exec api curl http://db:5432
Path mental:
Tidak perlu publish port DB ke host untuk API container mengakses DB. Publish port hanya untuk akses dari luar network container.
6.3 Bridge Traffic Path: Host ke Container
Jika host memanggil localhost:8080 dan container di-publish:
docker run -p 8080:8080 my-api
curl http://localhost:8080
Path mental:
Port publishing bukan mengubah container agar memakai host port. Ia membuat host menerima traffic lalu meneruskannya ke container endpoint.
7. Port Publishing: Host Port, Container Port, Bind Address
Flag umum:
docker run -p 8080:80 nginx
Artinya:
- host menerima traffic di port
8080; - Docker meneruskan ke container port
80; - process di container harus benar-benar listen di port
80; - by default binding dapat terbuka pada semua interface host, tergantung konfigurasi dan platform.
Format eksplisit:
docker run -p 127.0.0.1:8080:80 nginx
docker run -p 0.0.0.0:8080:80 nginx
docker run -p 192.168.1.10:8080:80 nginx
| Format | Makna |
|---|---|
-p 8080:80 | Publish container port 80 ke host port 8080 |
-p 127.0.0.1:8080:80 | Hanya listen di loopback host |
-p 0.0.0.0:8080:80 | Listen di semua IPv4 interface host |
-p 8080 | Pilih random host port untuk container exposed port |
-P | Publish semua exposed ports ke random host ports |
7.1 EXPOSE Bukan Publish
Dockerfile:
EXPOSE 8080
EXPOSE adalah metadata/documentation. Ia tidak otomatis membuka port ke host.
Untuk akses host:
docker run -p 8080:8080 my-api
7.2 Kesalahan Umum: App Listen di 127.0.0.1
Di dalam container, aplikasi harus listen pada interface yang dapat dicapai dari network container. Banyak framework default listen di 127.0.0.1, yang berarti hanya loopback container.
Buruk:
node server.js --host 127.0.0.1 --port 8080
Lebih benar untuk container:
node server.js --host 0.0.0.0 --port 8080
Kenapa?
127.0.0.1di container hanya bisa diakses dari container itu sendiri;- Docker port publishing meneruskan traffic ke container IP, bukan ke loopback-only listener;
- process harus bind ke
0.0.0.0atau container interface.
Debug:
docker exec api ss -ltnp
Cari apakah service listen pada:
127.0.0.1:8080 # suspicious for published service
0.0.0.0:8080 # usually expected
:::8080 # IPv6/all interface depending app
8. The Localhost Trap
Ini salah satu konsep paling penting.
8.1 Dari Container ke Container
Jika api dan db berada dalam network Compose yang sama:
api -> db:5432
Bukan:
api -> localhost:5432
Karena localhost dari api berarti api sendiri.
8.2 Dari Host ke Container
Host mengakses container lewat published port:
host -> localhost:8080 -> api:8080
8.3 Dari Container ke Host
Di Docker Desktop, ada special DNS name umum:
host.docker.internal
Di Linux Engine native, behavior bisa berbeda. Untuk Linux modern, sering digunakan host gateway mapping:
docker run --add-host=host.docker.internal:host-gateway my-app
atau Compose:
services:
api:
extra_hosts:
- "host.docker.internal:host-gateway"
Namun desain yang lebih baik: jangan membuat container terlalu bergantung pada service di host kecuali memang untuk development. Untuk production-like local environment, jalankan dependency sebagai container juga.
Diagram localhost semantics:
Rule of thumb:
- from host to container: use
localhost:<published-host-port>; - from container to sibling container: use
<service-name>:<container-port>; - from container to host: use explicit host gateway mechanism;
- from container to itself: use
localhost.
9. Docker DNS and Service Discovery
User-defined Docker networks provide embedded DNS service. Container dapat resolve container lain menggunakan name/alias.
Contoh:
docker network create app-net
docker run -d --name postgres --network app-net postgres:16
docker run --rm --network app-net alpine getent hosts postgres
Compose default behavior:
services:
api:
build: .
db:
image: postgres:16
Compose membuat network default untuk project. Container service api bisa resolve db.
postgres://db:5432/app
Bukan:
postgres://localhost:5432/app
9.1 Service Name vs Container Name
Di Compose, gunakan service name sebagai stable DNS name.
Baik:
http://catalog-api:8080
Kurang baik:
container_name: catalog-api
container_name sering mengganggu scaling karena nama container harus unik. Gunakan service name dan network alias bila perlu.
9.2 Network Alias
services:
api:
image: my-api
networks:
backend:
aliases:
- internal-api
networks:
backend:
Gunakan alias untuk compatibility, bukan untuk menyembunyikan model service yang buruk.
9.3 DNS TTL and Connection Reuse
Aplikasi sering cache DNS atau connection pool. Saat container diganti, DNS bisa berubah tetapi connection lama masih menunjuk endpoint lama.
Failure mode:
- service restart;
- IP container berubah;
- client tetap memakai connection lama;
- request gagal sampai pool refresh.
Solusi:
- implement retry dengan backoff;
- gunakan connection pool health validation;
- jangan hardcode container IP;
- gunakan service name;
- desain aplikasi tahan terhadap reconnect.
10. Host Network Driver
host network driver menghilangkan network namespace isolation. Container memakai network stack host.
docker run --network host my-api
Konsekuensi:
- process container listen langsung di host port;
- tidak perlu
-p; - port conflict langsung dengan host process;
localhostdi container adalah localhost host;- isolation berkurang;
- cocok untuk use case tertentu, bukan default.
Kapan masuk akal:
- low-latency network path;
- agent yang harus melihat network host;
- local diagnostic tools;
- service discovery/monitoring tertentu;
- development khusus.
Kapan sebaiknya dihindari:
- multi-service app biasa;
- environment yang butuh network isolation;
- ketika port binding harus eksplisit;
- ketika security boundary penting;
- saat ingin portability ke Compose/Swarm/Kubernetes.
Diagram:
Decision heuristic:
Use
hostnetwork only when you can explain exactly which isolation you are giving up and why the performance/visibility benefit is worth it.
11. None Network Driver
none membuat container hanya punya loopback. Tidak ada external network.
docker run --network none alpine ip addr
Kapan digunakan:
- offline batch job;
- cryptographic processing yang tidak butuh network;
- malware/sample analysis sandbox tambahan;
- test yang ingin memastikan tidak ada outbound call;
- build or transform job dengan input/output via volume.
Contoh:
docker run --rm \
--network none \
-v "$PWD/input:/input:ro" \
-v "$PWD/output:/output" \
my-transformer:1.0
Security benefit:
- tidak bisa call external API;
- tidak bisa exfiltrate lewat network biasa;
- dependency harus eksplisit lewat file/volume.
Namun jangan menganggap none sebagai sandbox sempurna. Masih ada boundary lain: filesystem, capability, seccomp, user, resource, dan host mounts.
12. Macvlan and Ipvlan
macvlan membuat container terlihat seperti device tersendiri di network fisik. Container mendapat MAC address sendiri.
Kapan digunakan:
- legacy app butuh L2 adjacency;
- monitoring network appliance;
- DHCP/static IP integration;
- service harus muncul sebagai host terpisah di LAN;
- network policy enterprise mengharuskan identitas IP/MAC khusus.
Contoh konseptual:
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 lan-net
docker run --rm --network lan-net alpine ip addr
Trade-off:
- butuh koordinasi dengan network team;
- switch port/security policy bisa membatasi multiple MAC;
- host-to-container communication punya nuance;
- observability/NAT behavior berbeda dari bridge;
- tidak cocok untuk default local dev.
ipvlan mirip dalam tujuan integrasi network eksternal, tetapi dengan behavior L2/L3 yang berbeda. Pakai hanya bila model routing/VLAN dipahami.
Prinsip: macvlan/ipvlan adalah network architecture decision, bukan sekadar Docker flag.
13. Compose Networking Model Preview
Compose secara default membuat satu network per project.
services:
api:
build: .
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: example
# Compose implicitly creates: <project>_default
api dapat mengakses db:5432.
Lebih eksplisit:
services:
reverse-proxy:
image: nginx:alpine
ports:
- "8080:80"
networks:
- public
- backend
api:
build: ./api
networks:
- backend
- data
db:
image: postgres:16
networks:
- data
networks:
public:
backend:
data:
internal: true
Diagram:
Design rule:
- expose hanya edge service;
- internal service tidak perlu publish port;
- DB tidak perlu reachable dari host kecuali untuk dev/admin;
- pisahkan public/backend/data network bila boundary penting;
- gunakan service name, bukan IP.
14. Network Security Boundary
Docker network bukan firewall enterprise lengkap, tapi ia memberi isolation boundary penting.
14.1 Jangan Publish Port yang Tidak Perlu
Buruk:
services:
db:
image: postgres:16
ports:
- "5432:5432"
Jika hanya api yang perlu akses DB, cukup:
services:
db:
image: postgres:16
networks:
- data
Publish port DB hanya bila host benar-benar butuh akses. Untuk development, boleh tetapi bind ke loopback:
ports:
- "127.0.0.1:5432:5432"
14.2 Bind Address Matters
| Bind | Reachability |
|---|---|
127.0.0.1:8080:8080 | Hanya host lokal |
0.0.0.0:8080:8080 | Semua interface host |
192.168.1.10:8080:8080 | Interface tertentu |
Kesalahan bind address bisa mengubah service lokal menjadi service LAN/public.
14.3 Internal Network
Compose mendukung network internal:
networks:
data:
internal: true
Gunakan untuk network yang tidak perlu outbound external secara langsung. Tetapi tetap validasi behavior sesuai platform dan kebutuhan, karena DNS/proxy/routing bisa memiliki nuance.
15. Firewall, NAT, and Host Policy
Docker dapat memanipulasi firewall rules host untuk network dan port publishing. Di Linux, ini biasanya berhubungan dengan iptables/nftables.
Hal yang sering terjadi:
- port sudah published tetapi firewall host memblokir;
- corporate endpoint security mengubah packet filtering;
- distro firewall (
ufw,firewalld) punya interaksi tidak intuitif; - rules manual hilang setelah Docker restart;
- Docker Desktop menambahkan VM/network layer tambahan.
Debug layer:
docker ps
docker port api
docker inspect api
ss -ltnp
sudo iptables -S
sudo nft list ruleset
Production heuristic:
- jangan mengandalkan “default Docker opened it” sebagai security policy;
- documented firewall policy tetap harus eksplisit;
- bind sensitive local port ke
127.0.0.1; - audit published ports dalam CI/lint Compose;
- monitor exposed host ports.
16. IPv4, IPv6, MTU, and Proxy Nuance
16.1 IPv4 Assumption
Banyak tutorial Docker mengasumsikan IPv4 private subnet. Dalam environment modern, IPv6 bisa relevan. Pastikan aplikasi dan dependency tidak diam-diam gagal karena resolver mengembalikan IPv6 dulu.
Debug:
getent hosts service-name
curl -4 http://service-name:8080
curl -6 http://service-name:8080
16.2 MTU Problem
MTU mismatch bisa menyebabkan request kecil berhasil tetapi payload besar timeout/hang.
Gejala:
- TLS handshake random fail;
- HTTP upload/download besar gagal;
- service antar network tertentu timeout;
- VPN aktif memperburuk.
Debug awal:
ip link
docker network inspect app-net
ping -M do -s 1472 target
16.3 Corporate Proxy
Container tidak otomatis mewarisi semua proxy host.
Yang perlu diperiksa:
- daemon proxy untuk pull image;
- build proxy untuk
RUN apt-get/npm install; - runtime proxy untuk app outbound call;
NO_PROXYuntuk internal service name sepertidb,redis,.local, atau private subnet.
Kesalahan NO_PROXY sering membuat container mencoba mengakses internal service lewat corporate proxy.
17. Debugging Connectivity: Layer-by-Layer Method
Jangan debug networking secara acak. Gunakan urutan.
17.1 Pertanyaan 1 — Process Listen?
docker exec api ss -ltnp
Validasi:
- port benar;
- protocol benar TCP/UDP;
- bind address benar (
0.0.0.0vs127.0.0.1); - process masih hidup.
17.2 Pertanyaan 2 — Container Punya IP dan Route?
docker exec api ip addr
docker exec api ip route
Validasi:
- interface
eth0ada; - IP sesuai network;
- default route ada jika butuh outbound.
17.3 Pertanyaan 3 — DNS Resolve?
docker exec api getent hosts db
docker exec api nslookup db
Validasi:
- service name benar;
- container berada di network yang sama;
- tidak memakai
container_nameyang mengacaukan assumption; - resolver config benar.
17.4 Pertanyaan 4 — TCP Reachable?
docker exec api nc -vz db 5432
docker exec api curl -v http://web:8080/health
Validasi:
- packet sampai;
- service menerima;
- firewall internal tidak memblokir;
- protocol tidak salah.
17.5 Pertanyaan 5 — Host Port Published?
docker ps
docker port api
ss -ltnp | grep 8080
curl -v http://localhost:8080/health
Validasi:
- host port benar;
- bind address benar;
- tidak conflict;
- process dalam container listen pada container port yang benar.
17.6 Pertanyaan 6 — Network Object Benar?
docker network ls
docker network inspect app-net
Validasi:
- kedua container ada di network yang sama;
- subnet tidak overlap dengan VPN/corporate network;
- alias benar;
- internal flag sesuai.
Debug flow:
18. Common Failure Modes and Fixes
18.1 Connection refused from Host
Meaning: target reachable, no process accepting on that port, or NAT goes to port with no listener.
Check:
docker ps
docker port api
docker exec api ss -ltnp
Likely causes:
- app crashed;
- app listens on wrong port;
- app binds to
127.0.0.1inside container; - host port maps to wrong container port.
18.2 Connection timed out
Meaning: packet not reaching target or response not coming back.
Likely causes:
- firewall;
- wrong IP/host;
- route issue;
- network not shared;
- external service blocked;
- MTU/VPN issue.
18.3 Name or service not known
Likely causes:
- wrong service name;
- containers not on same user-defined network;
- using default bridge without proper DNS behavior;
- app using custom DNS/resolver incorrectly;
- Compose project/network mismatch.
18.4 Works from Host, Fails from Container
Likely causes:
- using
localhostinside container; - proxy missing;
- DNS difference;
- outbound firewall;
- host service only binds to
127.0.0.1and container cannot reach it through host gateway; - Docker Desktop VM boundary.
18.5 Works in Compose, Fails in CI
Likely causes:
- CI uses different project name;
- port conflict on shared runner;
- service readiness not guaranteed;
- DNS name depends on
container_name; - network cleanup stale;
- test starts before dependency is ready.
19. Network Design Patterns
19.1 Edge/Internal Split
Expose only reverse proxy or API gateway.
services:
proxy:
image: nginx
ports:
- "127.0.0.1:8080:80"
networks: [edge, app]
api:
image: my-api
networks: [app, data]
db:
image: postgres
networks: [data]
networks:
edge:
app:
data:
internal: true
Benefits:
- DB not published;
- API not directly published if proxy handles edge;
- data network restricted;
- topology documents intent.
19.2 Per-Bounded-Context Network
For larger local environments:
networks:
identity:
billing:
case-management:
shared-observability:
Do not put every service in one giant network unless the whole app is intentionally flat.
19.3 Admin Network
Admin tools should not be on same public path by default.
services:
pgadmin:
image: dpage/pgadmin4
profiles: [admin]
ports:
- "127.0.0.1:5050:80"
networks: [data]
Run only when needed:
docker compose --profile admin up pgadmin
20. Anti-Patterns
20.1 Publishing Every Service
Bad:
services:
api:
ports: ["8080:8080"]
db:
ports: ["5432:5432"]
redis:
ports: ["6379:6379"]
rabbitmq:
ports: ["5672:5672"]
Better:
- publish only what host needs;
- bind admin/dev ports to
127.0.0.1; - internal dependencies use service discovery.
20.2 Hardcoding Container IP
Bad:
DB_HOST=172.20.0.3
Good:
DB_HOST=db
Container IP can change. Service name is the contract.
20.3 Using container_name Everywhere
Bad:
services:
api:
container_name: api
Problems:
- prevents scaling;
- creates global name conflicts;
- makes project isolation harder;
- hides Compose service model.
Use service name. Use alias only when necessary.
20.4 Using Host Network to Avoid Learning Networking
Bad reasoning:
“Bridge networking is confusing, so use
--network host.”
This trades confusion for weaker isolation and less portability.
Use host network only when the requirement demands it.
20.5 Relying on Startup Order as Readiness
Network path existing does not mean dependency is ready.
depends_on order is not enough unless paired with health semantics where supported. This will be covered deeply in Compose parts.
21. Practice Lab
Lab 1 — Bridge Service Discovery
Create network:
docker network create lab-net
Run Nginx:
docker run -d --name web --network lab-net nginx:alpine
Resolve and call it:
docker run --rm --network lab-net alpine sh -c \
"apk add --no-cache curl >/dev/null && getent hosts web && curl -I http://web"
Observe:
docker network inspect lab-net
Questions:
- What IP does
webhave? - Where does DNS name come from?
- Is port 80 published to host?
- Can host call
http://localhost:80?
Lab 2 — Port Publishing
docker run -d --name web-published -p 127.0.0.1:8080:80 nginx:alpine
curl -I http://localhost:8080
docker port web-published
Questions:
- What is host port?
- What is container port?
- Why does
EXPOSE 80alone not publish?
Lab 3 — Localhost Trap
Run DB:
docker network create trap-net
docker run -d --name db --network trap-net postgres:16 \
-e POSTGRES_PASSWORD=example
From another container:
docker run --rm --network trap-net postgres:16 \
psql postgresql://postgres:example@db:5432/postgres -c 'select 1'
Try wrong host:
docker run --rm --network trap-net postgres:16 \
psql postgresql://postgres:example@localhost:5432/postgres -c 'select 1'
Explain why it fails.
Lab 4 — None Network
docker run --rm --network none alpine ip addr
docker run --rm --network none alpine ping -c 1 8.8.8.8
Questions:
- Which interface exists?
- What failure do you see?
- When is this useful?
Lab 5 — Inspect a Compose Network
Create compose.yaml:
services:
api:
image: nginx:alpine
ports:
- "127.0.0.1:8081:80"
client:
image: alpine
command: sleep infinity
Run:
docker compose up -d
docker compose exec client wget -qO- http://api
docker network ls
docker network inspect $(basename "$PWD")_default
Questions:
- What network did Compose create?
- How did
clientresolveapi? - Why does host use
localhost:8081but client usesapi:80?
Cleanup:
docker compose down
docker network rm lab-net trap-net || true
docker rm -f web web-published db || true
22. Review Checklist
Untuk setiap Dockerized application, tanyakan:
- service mana yang benar-benar perlu publish port ke host?
- published port bind ke
127.0.0.1atau semua interface? - dependency internal memakai service name, bukan IP?
- ada container yang memakai
localhostuntuk dependency lain? - ada network yang terlalu flat?
- DB/cache/message broker terekspos tanpa alasan?
- user-defined bridge dipakai untuk app multi-container?
container_namedipakai tanpa alasan kuat?- ada subnet conflict dengan VPN/corporate network?
- ada proxy/NO_PROXY requirement?
- health/readiness dipisahkan dari network reachability?
- debug tools tersedia untuk minimal image?
23. Key Takeaways
- Container memiliki network namespace sendiri;
localhostdi container bukan host. - User-defined bridge adalah default terbaik untuk single-host multi-container app.
- Port publishing menghubungkan host port ke container port;
EXPOSEhanya metadata. - Internal container-to-container traffic sebaiknya memakai service name dan container port.
- Jangan publish dependency internal tanpa alasan.
- Host network mengorbankan isolation; gunakan hanya bila benar-benar perlu.
noneberguna untuk workload offline atau restricted.- Macvlan/ipvlan adalah keputusan arsitektur jaringan, bukan default development shortcut.
- Debug networking harus layer-by-layer: process, port, DNS, route, TCP, firewall, protocol.
- Network design yang baik membuat dependency graph terlihat jelas dan mengurangi blast radius.
24. Transisi ke Part 012
Networking menjawab bagaimana container saling bicara. Part berikutnya membahas boundary yang sama pentingnya: storage.
Kita akan masuk ke:
- writable layer;
- copy-on-write;
- volumes;
- bind mounts;
- tmpfs;
- permission/ownership;
- backup/restore;
- storage driver mental model;
- stateful container pitfalls.
Jika networking salah, service tidak bisa berkomunikasi. Jika storage salah, data bisa hilang, corrupt, bocor ke host, atau membuat environment tidak reproducible.
You just completed lesson 11 in build core. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.
Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.