User-defined Network #
Jika ada satu konsep di Docker networking yang wajib dikuasai untuk aplikasi production, itu adalah user-defined network. Docker menyediakan banyak network driver, tapi untuk hampir semua skenario single-host, user-defined bridge adalah pilihan terbaik. Ia menggabungkan semua yang kita butuhkan: DNS internal, isolasi yang baik, konfigurasi fleksibel, dan service discovery yang stabil.
Banyak developer masih menggunakan default bridge (docker0) tanpa sadar keterbatasannya — tidak ada DNS internal, semua container di satu subnet, dan komunikasi antar container harus pakai IP address. User-defined network menyelesaikan semua masalah itu dengan satu perintah: docker network create.
Artikel ini membahas user-defined network secara mendalam: cara membuat, opsi konfigurasi (subnet, gateway, internal), multi-network per container, integrasi dengan Docker Compose, dan pola arsitektur untuk aplikasi production. Pada akhirnya, kamu akan bisa merancang topologi network container yang aman, scalable, dan mudah di-maintain.
Apa Itu User-defined Network? #
User-defined network adalah network yang kamu buat secara eksplisit dengan docker network create, bukan network bawaan yang otomatis dibuat Docker (bridge, host, none).
# Buat user-defined network
docker network create my-network
# Lihat semua network
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# abc123... bridge bridge local <- default
# def456... host host local <- default
# ghi789... none null local <- default
# jkl012... my-network bridge local <- kamu yang buat
Karakteristik user-defined network (default driver bridge):
- DNS internal otomatis — container bisa saling resolve via nama.
- Isolasi per network — container di network A tidak bicara ke network B.
- Container di banyak network — satu container bisa multi-network.
- Konfigurasi custom — subnet, gateway, IP range, driver tertentu.
- Service discovery — Compose otomatis pakai user-defined network.
User-defined network = best practice default. Untuk hampir semua kasus, docker network create my-net dan jalankan container di network itu. Default bridge hanya untuk eksperimen cepat.
Cara Membuat User-defined Network #
Sintaks Dasar #
docker network create [OPTIONS] NETWORK_NAME
Opsi yang paling sering dipakai:
| Opsi | Fungsi |
|---|---|
--driver |
Tipe driver (default: bridge) |
--subnet |
Custom subnet (CIDR) |
--gateway |
Custom gateway IP |
--ip-range |
Range IP untuk container |
--internal |
Network tanpa akses keluar |
--attachable |
Container bisa di-attach manual |
--label |
Metadata (untuk Compose, K8s) |
Contoh #
# Paling sederhana - Docker pilih semua default
docker network create app-network
# Custom subnet
docker network create \
--subnet=192.168.50.0/24 \
--gateway=192.168.50.1 \
custom-net
# Internal network (tidak ada akses internet)
docker network create --internal backend-net
# Multi-driver (overlay untuk Swarm)
docker network create --driver overlay swarm-net
Mengapa Default Bridge Tidak Cukup #
Default bridge (docker0) adalah bridge bawaan yang dibuat saat Docker Engine pertama kali install. Ia punya keterbatasan serius untuk aplikasi multi-container.
| Aspek | Default Bridge | User-defined Network |
|---|---|---|
| DNS internal | ❌ Tidak | ✅ Ya |
| Container name resolve | ❌ (harus IP atau --link) |
✅ |
| Service name (Compose) | ❌ | ✅ |
| Isolasi antar project | ❌ (semua di satu bridge) | ✅ |
| Multi-network per container | ❌ | ✅ |
| Custom subnet | ❌ | ✅ |
| Container scaling | Terbatas | Bebas |
# Default bridge - DNS tidak aktif
docker run -d --name web --network bridge nginx
docker run -d --name db --network bridge postgres
docker exec web sh -c 'ping -c 1 db'
# ping: bad address 'db' <- GAGAL
# User-defined - DNS aktif
docker network create app-net
docker run -d --name web --network app-net nginx
docker run -d --name db --network app-net postgres
docker exec web sh -c 'ping -c 1 db'
# PING db (172.18.0.2): 56 data bytes <- BERHASIL
Default bridge = anti-pattern untuk aplikasi multi-container. Jangan pakai untuk apa pun selain testing cepat atau container single yang berdiri sendiri.
Konfigurasi Custom Subnet dan Gateway #
Untuk kontrol lebih, kamu bisa set subnet, gateway, dan IP range sendiri.
docker network create \
--driver bridge \
--subnet 10.10.0.0/16 \
--gateway 10.10.0.1 \
--ip-range 10.10.1.0/24 \
--label env=production \
--label app=backend \
production-backend
Kapan perlu custom subnet?
- Avoid conflict dengan network lain — kalau host punya VPN dengan subnet
192.168.0.0/16, dan Docker default juga di range itu, bisa bentrok. - Predictable IP allocation — kalau kamu butuh container punya IP tertentu untuk alasan compliance.
- Multi-host setup — subnet yang terstruktur memudahkan routing.
# Inspect detail
docker network inspect production-backend
Output akan menunjukkan IPAM.Config dengan Subnet, Gateway, dan IPRange yang sudah di-custom.
Best practice: gunakan subnet yang mudah diingat dan tidak bentrok dengan range umum (10.0.0.0/8besar sekali,172.16.0.0/12medium,192.168.0.0/16kecil). Hindari192.168.0.0/24dan192.168.1.0/24karena bentrok dengan router rumah/kantor.
Internal Network: Total Isolasi dari Internet #
User-defined network bisa dibuat internal — tanpa gateway keluar, tanpa akses internet, tanpa NAT keluar.
docker network create --internal backend-net
Karakteristik internal network:
- Tidak ada gateway di routing table container.
- Container tidak bisa akses internet — DNS ke
8.8.8.8juga gagal. - Container tetap bisa bicara ke container lain di network yang sama.
- Cocok untuk: database, cache, message broker, internal service.
# docker-compose.yml
networks:
backend:
internal: true
frontend:
# Default - ada akses internet
# Verifikasi: container di internal network tidak bisa ping google
docker run --rm --network backend-net alpine ping -c 1 8.8.8.8
# ping: connect: Network is unreachable
Internal network = no internet, no exceptions. Ini bukan fitur yang bisa di-bypass. Kalau service di internal network tiba-tiba bisa akses internet, ada misconfiguration. Audit konfigurasi Docker dan iptables.
Multi-Network per Container: Layered Security #
Satu container bisa terhubung ke banyak user-defined network sekaligus. Ini adalah pola layered security yang umum.
# Container API yang bridge antara frontend dan backend
docker network create frontend
docker network create backend --internal
docker run -d --name api --network frontend my-api
docker network connect backend api
flowchart LR
subgraph Front["frontend (public)"]
W[web]
A[api]
end
subgraph Back["backend (internal)"]
A
D[(db)]
end
W --> A
A --> D
Container api punya interface di frontend (terbuka ke internet) dan backend (internal, tersembunyi). Ia jadi satu-satunya gateway. Database benar-benar tersembunyi — tidak bisa di-reach dari internet tanpa lewat api.
# docker-compose.yml - pola segmentasi
version: "3.9"
services:
web:
image: nginx
networks:
- frontend
api:
image: my-api
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
backend:
internal: true
User-defined Network di Docker Compose #
Docker Compose selalu membuat user-defined network untuk project, kecuali kamu override.
version: "3.9"
services:
web:
image: nginx
api:
image: my-api
db:
image: postgres
Tanpa deklarasi networks, Compose otomatis:
- Membuat satu network default:
<project>_default(misalmyapp_default). - Connect-kan semua service ke network itu.
- Aktifkan DNS internal berbasis service name.
docker compose up -d
docker network ls
# myapp_default bridge local <- dibuat otomatis
docker network inspect myapp_default
# Containers:
# - myapp-web-1
# - myapp-api-1
# - myapp-db-1
Multi-Network Custom di Compose #
version: "3.9"
services:
web:
image: nginx
networks:
- frontend
api:
image: my-api
networks:
- frontend
- backend
worker:
image: my-worker
networks:
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
name: my-frontend
backend:
name: my-backend
internal: true
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-backend
driver_opts.com.docker.network.bridge.namememungkinkan kamu set nama interface Linux bridge. Berguna untuk monitoring (tcpdump -i br-backend) atau audit (ip link showdi host).
User-defined Network untuk Multi-Host (Swarm) #
Untuk deployment multi-host, user-defined network bisa dibuat dengan driver overlay di Docker Swarm.
docker network create \
--driver overlay \
--subnet 10.0.0.0/16 \
--attachable \
swarm-net
Container yang di-deploy di Swarm otomatis tersebar di banyak host, tapi masih dalam satu network. Komunikasi lewat VXLAN tunnel di bawah.
flowchart LR
subgraph Host1["Host 1"]
C1A[Container A]
C1B[Container B]
end
subgraph Host2["Host 2"]
C2A[Container A]
C2B[Container C]
end
subgraph Host3["Host 3"]
C3A[Container C]
end
C1A <-->|VXLAN| C2A
C1B <-->|VXLAN| C2B
C2B <-->|VXLAN| C3A
# docker-stack.yml (Swarm mode)
version: "3.9"
services:
web:
image: nginx
networks:
- frontend
deploy:
replicas: 5
api:
image: my-api
networks:
- frontend
- backend
deploy:
replicas: 10
networks:
frontend:
driver: overlay
backend:
driver: overlay
internal: true
Container web di host berbeda tetap bisa saling menemukan via web (Swarm DNS load-balances ke replica terdekat). api di host berbeda bisa bicara ke db yang mungkin ada di host lain.
Topologi Arsitektur Umum #
Tier Tunggal: Single Network #
flowchart LR
N[app-network] --> W[web]
N --> A[api]
N --> D[(db)]
N --> C[(cache)]
Cocok untuk: development, single-host, MVP.
Tiga Tier: Edge-App-Data #
flowchart TB
subgraph Edge["edge"]
LB[Load Balancer]
end
subgraph App["app"]
API[API]
W1[Worker]
end
subgraph Data["data (internal)"]
DB[(DB)]
Cache[(Cache)]
Broker[(Kafka)]
end
LB --> API
API --> DB
API --> Cache
W1 --> Broker
Broker --> DB
Cocok untuk: production single-host, multi-service dengan segmentasi.
Multi-Tenant: Per-Tenant Network #
flowchart TB
subgraph A["tenant-a"]
AN[a-network]
A1[app]
A2[(db)]
end
subgraph B["tenant-b"]
BN[b-network]
B1[app]
B2[(db)]
end
Admin[admin-network] --> A1
Admin --> B1
Cocok untuk: SaaS, hosting environment, dev/staging/prod per customer.
Microservices dengan Broker #
flowchart LR
subgraph Edge["edge"]
GW[Gateway]
end
subgraph App["app"]
API1[API Service]
API2[Worker]
end
subgraph Broker["broker"]
K[(Kafka)]
end
subgraph Data["data"]
DB1[(DB 1)]
DB2[(DB 2)]
end
GW --> API1
API1 --> K
K --> API2
API1 --> DB1
API2 --> DB2
Cocok untuk: event-driven architecture, microservices besar.
Mengelola User-defined Network #
Inspeksi #
# Lihat semua network
docker network ls
# Detail network
docker network inspect my-network
# Berisi: driver, subnet, gateway, containers yang terhubung
# Lihat hanya container di network
docker network inspect my-network --format '{{range .Containers}}{{.Name}} {{end}}'
# IP satu container
docker network inspect my-network --format '{{json .Containers}}' | python3 -c "import json,sys; print(json.load(sys.stdin)['container-id']['IPv4Address'])"
Modifikasi #
# Hubungkan container ke network
docker network connect my-network existing-container
# Putuskan
docker network disconnect my-network existing-container
# Hapus network (harus tidak ada container)
docker network rm my-network
Cleanup #
# Hapus semua network yang tidak terpakai
docker network prune
# Hapus semua container + network
docker system prune --volumes
docker network rmgagal kalau masih ada container yang terhubung. Lepaskan container dulu (disconnect) atau hapus container-nya. Di Compose,docker compose downotomatis hapus network project.
User-defined Network vs Default Bridge: Kapan Pakai Yang Mana #
| Situasi | Pilihan |
|---|---|
| Eksperimen cepat 1 container | Default bridge (atau tidak perlu network sama sekali) |
| Multi-container development | User-defined network |
| Production dengan banyak service | User-defined network + segmentasi |
| Multi-host (Swarm, K8s) | User-defined network dengan driver overlay/calico |
| Sandbox tanpa network | None network |
| High-performance | Host network (tapi hati-hati) |
Praktis: untuk 95% kasus, user-defined bridge adalah pilihan benar. Sisanya 5% adalah kasus khusus yang memang butuh mode lain.
Best Practice User-defined Network #
1. Selalu Pakai User-defined untuk Multi-Container #
# ✓ Best practice
docker network create app-net
docker run --network app-net --name db postgres
docker run --network app-net --name api my-api
2. Segmentasi Berdasarkan Layer #
networks:
edge: # public-facing
app: # business logic
data: # internal: true, no internet
3. Pakai Nama Network yang Deskriptif #
# ✓ Bagus
docker network create frontend-prod
docker network create backend-prod
docker network create data-prod
# ✗ Kurang bagus
docker network create net1
docker network create net2
4. Custom Subnet untuk Hindari Konflik #
# Hindari range umum 192.168.x.x (rumah) dan 10.x.x.x (banyak dipakai)
docker network create --subnet 172.25.0.0/16 app-net
5. Internal Network untuk Service Sensitif #
networks:
data:
internal: true # database, cache, broker
6. Docker Compose: Biarkan Default, atau Custom Eksplisit #
# Default (Compose auto-create satu network)
services:
web:
api:
# Custom eksplisit (untuk kontrol penuh)
services:
web:
networks: [frontend]
api:
networks: [frontend, backend]
networks:
frontend:
backend:
internal: true
7. Cleanup Rutin #
# Hapus network orphaned
docker network prune
# Atau semua unused sekaligus
docker system prune
Migrasi dari Default Bridge ke User-defined #
Kalau proyekmu sudah terlanjur pakai default bridge, migrasinya mudah:
# 1. Buat user-defined network
docker network create app-net
# 2. Hubungkan semua container yang ada
for container in web api db; do
docker network connect app-net $container
done
# 3. Test komunikasi
docker exec web ping api
# 4. Update docker-compose.yml untuk masa depan
# Update docker-compose.yml
version: "3.9"
services:
web:
networks: [app-net]
api:
networks: [app-net]
db:
networks: [app-net]
networks:
app-net:
Ringkasan #
- User-defined network = network yang kamu buat sendiri dengan
docker network create. Ia mengatasi semua keterbatasan default bridge.- Wajib pakai untuk aplikasi multi-container, production, atau yang butuh service discovery via nama.
- DNS internal otomatis — container resolve nama container atau service name tanpa konfigurasi tambahan.
- Konfigurasi lengkap:
--subnet,--gateway,--ip-range,--internal,--driver,--label. Subnet custom menghindari konflik dengan network host.- Internal network = tidak ada akses internet. Wajib untuk database, cache, broker, dan service yang tidak boleh punya akses keluar.
- Multi-network per container memungkinkan layered security: container API di
frontenddanbackend, jadi gateway yang bisa diaudit.- Docker Compose otomatis membuat user-defined network. Untuk kontrol penuh, deklarasi
networks:di Compose dan assign per-service.- Multi-host (Swarm, K8s): user-defined network dengan driver overlay, atau driver eksternal (Calico, Flannel, Cilium).
- Default bridge = anti-pattern untuk multi-container. Hanya untuk eksperimen cepat atau single container.
- Best practice: segmentasi per layer (edge/app/data), nama network deskriptif, internal untuk service sensitif, custom subnet untuk hindari konflik.
- Prinsip utama: container yang bekerja sama → user-defined network. Container standalone → default bridge cukup. Container publik → port mapping minimal dan segmentasi jelas.
- Migrasi dari default bridge ke user-defined mudah: create network, connect existing container, update Compose.
← Sebelumnya: Network Isolation Berikutnya: Apa itu Dockerfile? →