Skip to content
VDS · Docker dan kontainer

Jaringan Docker dan port forwarding

Bagaimana container saling melihat, bagaimana publishing port berbeda dari EXPOSE sederhana, dan mengapa Docker melewati aturan ufw.

Diperbarui 23 Agustus 2026

Separuh masalah container berkaitan dengan jaringan: sebuah layanan tidak dapat menjangkau database, port sudah dipakai, panel tiba-tiba terbuka ke seluruh internet. Mari kita bedah cara kerjanya.

Tiga jenis jaringan

  • bridge — default. Container mendapat alamat internal dan saling berkomunikasi; mereka keluar melalui NAT host.
  • host — container menggunakan jaringan host secara langsung; publikasi port tidak diperlukan dan tidak berfungsi. Cepat, tetapi tanpa isolasi: port 80 container adalah port 80 host.
  • none — tanpa jaringan sama sekali. Untuk tugas yang tidak membutuhkannya.

Jaringan kustom yang Anda buat atau dibuat oleh Compose berbeda dari bridge default dalam satu hal penting: resolusi nama berfungsi di dalamnya. Container app dapat menjangkau container db dengan nama db.

docker network create backend
docker network ls
docker network inspect backend

Di Compose, jaringan semacam itu dibuat secara otomatis untuk setiap proyek.

Publikasi port

ports:
  - "127.0.0.1:8080:8080"   # accessible only from the machine itself
  - "80:80"                 # accessible to the whole internet

Di sebelah kiri adalah port pada host, di sebelah kanan adalah port di dalam container. Direktif EXPOSE pada image tidak mempublikasikan apa pun: itu hanya catatan tentang port mana yang didengarkan aplikasi.

Aturannya sederhana: publikasikan hanya yang harus dapat diakses dari luar. Database, panel, dan API internal dipasang pada 127.0.0.1, dan web server dengan sertifikat membukanya ke luar.

Docker menulis aturan iptables sendiri dan melakukannya sebelum chain yang dikelola oleh ufw. Port yang dipublikasikan sebagai -p 8080:8080 akan dapat diakses dari internet meskipun ufw menunjukkan “deny”. Jangan mengandalkan firewall — ikat port ke 127.0.0.1.

Komunikasi antar container

services:
  app:
    networks: [frontend, backend]
  db:
    networks: [backend]
  proxy:
    networks: [frontend]
    ports:
      - "80:80"
      - "443:443"

networks:
  frontend:
  backend:

Di sini database hanya dapat diakses oleh aplikasi, dan hanya web server yang menghadap ke luar. Ini adalah konfigurasi yang tepat untuk stack apa pun.

Di dalam container, rujuk container tetangga dengan nama layanannya: postgres://db:5432/app. Alamat localhost di dalam container berarti container itu sendiri, bukan host — kesalahan paling umum kedua setelah latest.

Untuk menjangkau layanan yang berjalan di host itu sendiri dari container, gunakan nama host.docker.internal dengan menambahkan:

extra_hosts:
  - "host.docker.internal:host-gateway"

Diagnostik

docker compose exec app ping -c2 db
docker compose exec app getent hosts db
sudo ss -tulpn | grep LISTEN
docker port <container>

ss akan menunjukkan antarmuka mana yang sebenarnya didengarkan oleh suatu port: 0.0.0.0:8080 — terbuka ke luar, 127.0.0.1:8080 — tidak.

Kesalahan umum

  • “Port already in use”. Port tersebut dipakai oleh container lain atau layanan host. sudo ss -tulpn | grep :80 akan menemukan penyebabnya.
  • Container di proyek Compose yang berbeda tidak dapat saling melihat. Setiap proyek memiliki jaringannya sendiri. Hubungkan secara eksplisit melalui networks: { shared: { external: true } }.
  • Aplikasi mendengarkan pada 127.0.0.1 di dalam container. Maka publikasi tidak akan membantu: Anda tidak dapat menjangkaunya dari luar container. Konfigurasikan aplikasi untuk mendengarkan pada 0.0.0.0.
  • Bandwidth. Hingga 500 Mbps dibagi per host. Distribusi file membaginya dengan semua hal lain.