Bridge Network #

Di antara semua network driver yang tersedia di Docker, bridge adalah yang paling sering kamu temui — bahkan mungkin tanpa kamu sadari. Setiap kali kamu menjalankan docker run tanpa argumen --network, container otomatis masuk ke default bridge. Di balik kesederhanaan perintah itu, ada arsitektur yang elegan: virtual switch, veth pair, IPAM, dan iptables NAT yang bekerja sama untuk memberikan container akses jaringan yang terisolasi tapi fungsional.

Bridge adalah pondasi yang harus kamu pahami sebelum melompat ke driver lain (host, overlay, macvlan). Setelah paham bridge, semua driver lain terasa seperti variasi dari konsep yang sama — hanya berbeda di tingkat isolasi dan cakupan.

Artikel ini membahas bridge secara mendalam: cara kerjanya di level OS, perbedaan default bridge dengan user-defined bridge, kenapa yang satu jauh lebih direkomendasikan, dan bagaimana bridge berinteraksi dengan NAT, port mapping, dan DNS. Pada akhirnya kamu akan bisa merancang topologi network multi-container yang aman dan scalable.

Apa Itu Bridge Network? #

Bridge network di Docker adalah virtual switch layer-2 yang berjalan di dalam host. Switch ini menghubungkan banyak container sekaligus dan meneruskan paket Ethernet di antara mereka. Secara konseptual, bridge = virtual network switch, dan container = perangkat yang tercolok ke switch itu.

flowchart LR
    subgraph Bridge["docker0 (bridge virtual)"]
        direction LR
        B("(docker0<br/>172.17.0.1")"))
    end

    C1["Container A<br/>172.17.0.2"] ---|veth| Bridge
    C2["Container B<br/>172.17.0.3"] ---|veth| Bridge
    C3["Container C<br/>172.17.0.4"] ---|veth| Bridge
    Bridge ---|iptables NAT| Net[Host network]
    Net --- Internet("(Internet"))

Karakteristik utama bridge network:

  • Container punya IP private di subnet yang dikelola Docker (misal 172.17.0.0/16).
  • Container di bridge yang sama bisa saling bicara langsung (L2 forwarding).
  • Container di bridge berbeda tidak bisa saling bicara tanpa routing eksplisit.
  • Akses keluar (ke internet atau LAN) lewat NAT di iptables.
  • Akses masuk (dari host atau luar) hanya lewat port mapping (-p).

Bridge bukan hal baru di dunia Linux. Ia sudah ada sejak lama sebagai fitur brctl / iproute2. Docker hanya memaketkannya dengan rapi, ditambah integrasi dengan iptables, IPAM, dan DNS server internal.

Kenapa disebut “bridge”? Karena ia meng-copy behavior physical network bridge (layer-2 switch). Paket di-forward berdasarkan MAC address, bukan IP. Ini yang membuat komunikasi antar container sangat cepat untuk traffic internal.

Default Bridge vs User-Defined Bridge #

Docker menyediakan dua jenis bridge, dan perbedaan di antara keduanya adalah salah satu hal paling penting untuk dipahami.

Default Bridge (bridge) #

Saat Docker Engine pertama kali berjalan, ia membuat satu bridge bawaan bernama bridge (di host, interface Linux-nya bernama docker0). Semua container yang dijalankan tanpa --network akan otomatis masuk ke bridge ini.

# Container otomatis masuk ke default bridge
docker run -d --name web nginx

# Lihat network tempat container terhubung
docker inspect web --format '{{.NetworkSettings.Networks}}'

Karakteristik default bridge:

Aspek Default Bridge
Nama network bridge
Subnet 172.17.0.0/16 (default)
DNS internal ❌ Tidak ada
Resolusi nama Hanya via IP atau link legacy
Isolasi Semua container di bridge yang sama
Port mapping Mendukung -p

Keterbatasan terbesar: tidak ada DNS internal. Container web tidak bisa menghubungi container db dengan hostname db. Kamu harus tahu IP address-nya.

# Cara lama (tidak disarankan): hardcode IP
ping 172.17.0.3
Anti-pattern: Meninggalkan container di default bridge untuk aplikasi multi-container. Tidak ada DNS, tidak ada isolasi antar project, semua container berbagi satu subnet. Untuk eksperimen boleh; untuk aplikasi serius, jangan.

User-Defined Bridge (Direkomendasikan) #

Kamu bisa membuat bridge sendiri dengan docker network create. Inilah yang disebut user-defined bridge — dan ini yang harus kamu pakai untuk hampir semua skenario serius.

# Buat user-defined bridge
docker network create app-network

# Jalankan container di network itu
docker run -d --name web --network app-network nginx
docker run -d --name db  --network app-network postgres

Sekarang web bisa menghubungi db cukup dengan hostname db:

docker exec web ping db
# PING db (172.18.0.3): 56 data bytes
# 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.087 ms

Karakteristik user-defined bridge:

Aspek User-Defined Bridge
Nama Bebas (misal app-network, backend-net)
Subnet Otomatis atau custom (--subnet)
DNS internal ✅ Otomatis aktif
Resolusi nama Container name DAN alias
Isolasi Per network, lebih terisolasi
Container di multiple network ✅ Mendukung
Port mapping Mendukung -p
Best practice: Untuk setiap proyek multi-container, selalu buat user-defined bridge. Bahkan untuk dua container saja, lebih baik eksplisit. Ini melatih kamu untuk memikirkan topologi network, bukan asal docker run.

Perbandingan Langsung #

Fitur Default Bridge User-Defined Bridge
DNS otomatis
Isolasi per project ❌ (semua di satu bridge) ✅ (network terpisah)
Container bisa di banyak network
--link (legacy) ❌ (tidak diperlukan)
Custom subnet / gateway
Cocok untuk Eksperimen, single container Aplikasi multi-container

Bagaimana Bridge Bekerja di Level OS #

Sekarang masuk ke bagian yang lebih teknis. Memahami apa yang terjadi di level OS membantu kamu debug saat ada masalah dan paham kenapa konfigurasi tertentu tidak berjalan seperti yang diharapkan.

1. Linux Bridge Interface #

Saat user-defined bridge dibuat, Docker membuat interface bridge di host:

docker network create app-network
ip link show
# br-abc123: <BROADCAST,MULTICAST,UP,LOWER_UP>
#     inet 172.18.0.1/16 brd 172.18.255.255

Interface br-abc123 adalah bridge itu sendiri. Ia punya IP (gateway) dan akan menjadi titik koneksi semua container di network.

2. Network Namespace #

Setiap container berjalan di network namespace terpisah. Namespace ini punya:

  • Interface sendiri (biasanya eth0).
  • Routing table sendiri.
  • Loopback lo sendiri.

Container di network bridge yang sama berada di namespace berbeda, tapi terhubung lewat veth pair ke bridge yang sama.

3. Virtual Ethernet (veth) Pair #

Docker membuat veth pair untuk setiap container — dua interface virtual yang selalu terhubung:

  • Ujung pertama masuk ke namespace container (muncul sebagai eth0).
  • Ujung kedua tetap di namespace host, tercolok ke bridge.
flowchart LR
    subgraph CN["Container Namespace"]
        eth0["eth0"]
    end

    subgraph HN["Host Namespace"]
        veth["veth-xxx@br-net"]
    end

    eth0 <-->|veth| veth

Paket yang dikirim container lewat eth0 akan muncul di ujung veth di host, lalu di-forward oleh bridge ke container tujuan.

4. IPAM (IP Address Management) #

Docker mengelola alokasi IP address container secara otomatis lewat IPAM driver. Untuk setiap network, IPAM:

  • Menentukan subnet (default-nya random di range 172.x.0.0/16).
  • Memberi IP unik ke tiap container.
  • Menentukan gateway.

Kamu bisa override:

docker network create \
  --subnet=192.168.10.0/24 \
  --gateway=192.168.10.1 \
  --ip-range=192.168.10.0/25 \
  custom-net

5. NAT dan iptables #

Agar container bisa keluar ke internet, Docker menambah aturan iptables MASQUERADE:

# Lihat rule NAT (simplified)
iptables -t nat -L POSTROUTING
# Chain POSTROUTING
# -A POSTROUTING -s 172.18.0.0/16 ! -o br-abc123 -j MASQUERADE

Artinya: paket dari subnet 172.18.0.0/16 yang keluar bukan lewat bridge itu sendiri akan di-MASQUERADE (source-nya diganti IP host). Hasilnya, dari sisi internet yang terlihat adalah host, bukan container.

Skema Lengkap di Level OS #

flowchart LR
    subgraph CT["Container Namespace"]
        E[eth0: 172.18.0.2]
    end
    subgraph HT["Host Namespace"]
        V[veth-xxx@br-abc]
        B[br-abc123: 172.18.0.1]
        HV[eth0: 192.168.1.10]
    end
    subgraph K["Kernel"]
        RT[Routing Table]
        IPT[iptables NAT]
    end
    NET[Internet]

    E <-->|l2| V
    V --> B
    B --> RT
    RT --> IPT
    IPT --> HV
    HV --> NET

Saat container mengirim paket ke internet:

  1. Paket keluar dari container lewat eth0.
  2. veth meneruskan ke bridge.
  3. Bridge mem-lookup destination — bukan local, jadi diteruskan ke routing table.
  4. Routing table memutuskan lewat interface eth0 host.
  5. iptables melakukan MASQUERADE — source IP diganti ke 192.168.1.10.
  6. Paket keluar ke internet.

Saat balasan datang: proses kebalikannya. Paket di-DNAT balik ke IP container (172.18.0.2) dan di-forward lewat bridge.


Port Mapping pada Bridge #

Bridge network bersifat private — container di dalamnya tidak otomatis bisa diakses dari host atau internet. Untuk membuka akses, kamu butuh port mapping (-p / --publish).

docker run -d --name web -p 8080:80 nginx

Artinya: port 8080 di host di-forward ke port 80 di container.

sequenceDiagram
    participant U as User
    participant H as Host:8080
    participant I as iptables DNAT
    participant B as Bridge
    participant C as Container:80

    U->>H: GET localhost:8080
    H->>I: Paket masuk
    I->>I: DNAT: 8080 -> 172.18.0.2:80
    I->>B: Forward
    B->>C: Sampai di container
    C-->>B: Response
    B-->>I: Kembali
    I-->>H: SNAT balik
    H-->>U: HTTP response

Kamu juga bisa bind ke IP tertentu di host:

# Hanya localhost yang bisa akses
docker run -p 127.0.0.1:8080:80 nginx

# IP spesifik (misal IP LAN host)
docker run -p 192.168.1.10:8080:80 nginx

# Random port di host
docker run -p 80 nginx
Bahaya: -p 8080:80 tanpa IP host akan bind ke 0.0.0.0 — artinya semua interface host menerima koneksi di port 8080. Kalau host punya IP publik, port ini akan terekspos ke internet. Untuk database atau service internal, selalu bind ke 127.0.0.1.

Isolasi: Bridge Memberikan Batas Alami #

Salah satu kekuatan bridge network yang sering tidak disadari adalah isolasi default-nya. Container di bridge A tidak bisa bicara ke container di bridge B tanpa konfigurasi tambahan.

docker network create frontend
docker network create backend

docker run -d --name web --network frontend nginx
docker run -d --name db  --network backend  postgres

Sekarang web tidak bisa akses db lewat network (karena beda network). Untuk menghubungkan keduanya, kamu bisa:

# Connect container web ke backend juga
docker network connect backend web

Atau lebih aman: buat container terpisah yang berfungsi sebagai gateway, misalnya API service yang terhubung ke kedua network.

flowchart LR
    subgraph Front["frontend network"]
        W[web]
        API[api]
    end
    subgraph Back["backend network"]
        API2[api - same container]
        DB["(db)"]
    end
    W --> API
    API <--> API2
    API2 --> DB

Container api punya dua interface — satu di frontend, satu di backend. Ia jadi jembatan yang bisa kamu kontrol, amati, dan audit. Database benar-benar tersembunyi dari frontend.


Bridge di Docker Compose #

Docker Compose secara default selalu membuat user-defined bridge untuk project. Kamu tidak perlu deklarasi network manual — Compose yang atur.

# docker-compose.yml
services:
  web:
    image: nginx
  db:
    image: postgres
  api:
    image: my-api

Tanpa deklarasi networks, Compose otomatis:

  • Membuat satu network bernama <project>_default.
  • Meng-connect-kan semua service ke network itu.
  • Mengaktifkan DNS internal berbasis service name.

Hasilnya, web bisa bicara ke api dengan http://api:8080, dan api bisa bicara ke db dengan db:5432 — tanpa konfigurasi tambahan.

Kalau kamu butuh network custom atau multi-network:

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  # tidak ada akses keluar ke internet
internal: true membuat network benar-benar terisolasi dari luar — tidak ada NAT keluar, tidak ada akses internet. Cocok untuk backend yang hanya boleh bicara ke service internal. Defense in depth murah tanpa extra config.

Kapan Bridge Network Tepat Digunakan #

Bridge network cocok untuk:

  • Local development dengan satu host.
  • Aplikasi multi-container (microservices) dalam satu host.
  • CI/CD pipeline yang menjalankan test dalam container.
  • Backend + database di satu server atau VM.
  • Single-host production deployment untuk aplikasi skala kecil-menengah.

Bridge network kurang cocok untuk:

  • Multi-host deployment (gunakan overlay untuk Swarm atau K8s).
  • Performa jaringan ekstrem (gunakan host network).
  • Sandbox tanpa network (gunakan none).
  • Integrasi langsung ke LAN fisik (gunakan macvlan).

Anti-Pattern dan Solusinya #

Berikut tiga jebakan paling umum saat menggunakan bridge network, dan cara mengatasinya.

1. Meninggalkan Container di Default Bridge #

# ✗ Anti-pattern: container di default bridge, harus pakai IP
docker run -d --name db postgres
docker run -d --name api my-api
# api tidak bisa pakai "db", harus pakai IP
# ✓ Solusi: user-defined bridge, DNS otomatis
docker network create app-net
docker run -d --name db  --network app-net postgres
docker run -d --name api --network app-net my-api
# api bisa pakai "db:5432"

2. Hardcode IP Container #

# ✗ Anti-pattern: hardcode IP
environment:
  DATABASE_HOST: 172.18.0.3  # bisa berubah saat restart
# ✓ Solusi: pakai service name
environment:
  DATABASE_HOST: db  # DNS resolve otomatis

3. Pakai Host Network untuk Mikroservice #

# ✗ Anti-pattern: host network untuk banyak service
services:
  web:
    network_mode: host
  db:
    network_mode: host
# Port bentrok, tidak ada isolasi
# ✓ Solusi: user-defined bridge
services:
  web:
    networks: [app]
  db:
    networks: [app]
networks:
  app:

Perintah Wajib untuk Bridge Network #

Sebelum lanjut, hafalkan perintah-perintah ini. Mereka akan jadi teman sehari-hari saat bekerja dengan bridge network.

# Lihat semua network (termasuk bridge default dan custom)
docker network ls

# Inspect detail satu network
docker network inspect app-network
# Akan menampilkan: subnet, gateway, container yang terhubung, IP per container

# Buat user-defined bridge dengan opsi lengkap
docker network create \
  --driver bridge \
  --subnet 192.168.50.0/24 \
  --gateway 192.168.50.1 \
  --ip-range 192.168.50.0/25 \
  my-custom-bridge

# Hubungkan container yang sudah jalan ke network lain
docker network connect app-network existing-container

# Putuskan dari network
docker network disconnect app-network existing-container

# Hapus network (pastikan tidak ada container yang terhubung)
docker network rm app-network

# Prune: hapus semua network yang tidak terpakai
docker network prune

Trik debugging yang sering berguna:

  • docker network inspect <nama> → lihat container mana saja yang terhubung dan IP-nya.
  • brctl show atau ip link show di host → lihat bridge interface dan veth yang tercolok.
  • iptables -t nat -L -n | grep <nama-network> → lihat rule NAT untuk network tersebut.

Ringkasan #

  • Bridge network adalah virtual switch layer-2 yang menghubungkan container di satu host. Ia adalah driver paling umum dan paling direkomendasikan untuk aplikasi single-host.
  • Default bridge (docker0) cocok untuk eksperimen, tapi tidak punya DNS internal dan semua container berbagi satu subnet.
  • User-defined bridge (docker network create my-net) adalah pilihan serius: ada DNS internal berbasis nama container, isolasi per project, dan konfigurasi subnet/gateway yang fleksibel.
  • Di balik layar, bridge bekerja dengan empat komponen: namespace (isolasi), veth pair (kabel virtual), bridge interface (switch), dan iptables (NAT + firewall).
  • Port mapping (-p) membuka akses dari host ke container. Tanpa -p, container hanya bisa bicara ke container lain di network yang sama — bukan ke host atau internet.
  • Isolasi antar bridge adalah batas keamanan alami. Pisahkan frontend, backend, dan database ke network berbeda untuk defense in depth.
  • Docker Compose selalu membuat user-defined bridge otomatis. Untuk multi-network atau internal: true, deklarasi manual network.
  • Anti-pattern utama: tinggal di default bridge, hardcode IP, pakai host network untuk microservices.
  • Bridge cocok untuk: local development, single-host deployment, microservices skala kecil-menengah, CI/CD. Kurang cocok untuk: multi-host, performa ekstrem, sandbox.

← Sebelumnya: Overview   Berikutnya: NAT →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact