Cara Menggunakan Docker Network dan Volume
Mengapa Docker Network dan Volume Penting?
Ketika bekerja dengan Docker untuk development lokal, dua fitur yang sering diabaikan adalah Docker network dan Docker volume. Padahal, keduanya adalah kunci untuk membuat environment development yang stabil, cepat, dan mudah dikelola.
Docker network memungkinkan container saling berkomunikasi tanpa expose port yang tidak perlu. Sementara Docker volume memastikan data persist meskipun container dihapus atau di-rebuild. Artikel ini akan membahas cara praktis menggunakan keduanya dalam workflow development sehari-hari.
Memahami Docker Network
Jenis-Jenis Network di Docker
Docker menyediakan beberapa driver network bawaan:
- bridge — default network, cocok untuk container di satu host
- host — container langsung pakai network host, tanpa isolasi
- none — container tanpa network sama sekali
Untuk development, kita hampir selalu pakai bridge network custom.
Membuat Custom Bridge Network
Mengapa custom network, bukan default bridge? Karena custom network mendukung DNS resolution otomatis antar container berdasarkan nama.
# Buat custom network
docker network create dev-network
# Verifikasi
docker network ls
Dengan custom network, container bisa saling akses menggunakan nama container sebagai hostname. Tidak perlu lagi hardcode IP address.
Contoh: Menghubungkan App dan Database
Misalnya kita punya aplikasi Laravel dan PostgreSQL:
# Jalankan PostgreSQL di custom network
docker run -d \
--name dev-postgres \
--network dev-network \
-e POSTGRES_DB=app_dev \
-e POSTGRES_USER=dev \
-e POSTGRES_PASSWORD=secret123 \
postgres:16-alpine
# Jalankan aplikasi Laravel
docker run -d \
--name dev-app \
--network dev-network \
-p 8000:8000 \
my-laravel-app
Di file .env Laravel, cukup set:
DB_HOST=dev-postgres
DB_PORT=5432
DB_DATABASE=app_dev
DB_USERNAME=dev
DB_PASSWORD=secret123
Perhatikan DB_HOST=dev-postgres — ini adalah nama container, bukan IP. Docker DNS akan resolve otomatis selama keduanya berada di network yang sama.
Memahami Docker Volume
Masalah Tanpa Volume
Tanpa volume, semua data di dalam container bersifat ephemeral. Artinya:
- Rebuild container = data hilang
- Database di-restart = semua record hilang
- Upload file dari user = lenyap
Ini jelas tidak ideal, bahkan untuk development.
Jenis Volume di Docker
Ada dua cara utama mount data di Docker:
1. Named Volume — dikelola Docker, lokasi di host abstrak:
docker volume create pgdata
docker run -d \
--name dev-postgres \
-v pgdata:/var/lib/postgresql/data \
postgres:16-alpine
2. Bind Mount — langsung map folder host ke container:
docker run -d \
--name dev-app \
-v $(pwd)/src:/var/www/html \
my-laravel-app
Kapan Pakai Named Volume vs Bind Mount?
| Kebutuhan | Pilihan | Alasan |
|---|---|---|
| Data database | Named volume | Performa lebih baik, Docker kelola lifecycle |
| Source code | Bind mount | Perlu edit langsung dari host/IDE |
| Cache/dependency | Named volume | Tidak perlu akses langsung, performa penting |
| Upload/storage | Named volume | Persist antar rebuild |
Praktik: Setup Lengkap dengan Docker Compose
Sekarang kita gabungkan network dan volume dalam satu docker-compose.yml yang realistis:
version: "3.8"
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- ./src:/var/www/html # bind mount: source code
- vendor:/var/www/html/vendor # named volume: dependency
networks:
- dev-network
depends_on:
- postgres
- redis
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: app_dev
POSTGRES_USER: dev
POSTGRES_PASSWORD: secret123
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- dev-network
redis:
image: redis:7-alpine
volumes:
- redisdata:/data
networks:
- dev-network
volumes:
pgdata:
redisdata:
vendor:
networks:
dev-network:
driver: bridge
Penjelasan Konfigurasi
Beberapa poin penting dari konfigurasi di atas:
- Source code di-bind mount agar perubahan langsung terdeteksi tanpa rebuild
- Vendor/dependency pakai named volume agar
composer installtidak lambat di macOS/Windows - Database data pakai named volume agar persist antar
docker compose downdanup - Semua service terhubung via
dev-network, bisa saling akses pakai nama service
Menjalankan dan Mengelola
# Start semua service
docker compose up -d
# Cek status
docker compose ps
# Lihat log aplikasi
docker compose logs -f app
# Stop tanpa hapus volume
docker compose down
# Stop DAN hapus volume (reset total)
docker compose down -v
Perhatikan perbedaan down dan down -v. Tanpa flag -v, named volume tetap ada. Data database aman. Dengan -v, semua volume dihapus — berguna ketika ingin reset environment dari nol.
Tips Performa Volume di macOS dan Windows
Jika kamu develop di macOS atau Windows, bind mount bisa terasa lambat karena file system sharing antara host dan VM Docker. Beberapa solusi:
1. Gunakan Cached atau Delegated Mount
volumes:
- ./src:/var/www/html:cached
Flag cached memberitahu Docker bahwa sedikit delay sinkronisasi dari container ke host itu OK. Ini meningkatkan performa read di container secara signifikan.
2. Pisahkan Dependency ke Named Volume
Seperti contoh di atas, folder vendor atau node_modules sebaiknya pakai named volume:
volumes:
- ./:/app
- node_modules:/app/node_modules
Ini mencegah ribuan file dependency di-sync bolak-balik antara host dan container.
3. Gunakan Docker Compose Watch (v2.22+)
Fitur baru Docker Compose yang lebih efisien dari bind mount untuk hot reload:
services:
app:
develop:
watch:
- action: sync
path: ./src
target: /var/www/html
- action: rebuild
path: package.json
Debugging Network dan Volume
Inspect Network
Ketika container tidak bisa connect satu sama lain:
# Lihat detail network
docker network inspect dev-network
# Cek container mana yang terhubung
docker network inspect dev-network --format '{{range .Containers}}{{.Name}} {{end}}'
# Test koneksi dari dalam container
docker exec -it dev-app ping dev-postgres
Inspect Volume
Ketika data sepertinya tidak persist:
# List semua volume
docker volume ls
# Lihat detail volume
docker volume inspect pgdata
# Cek isi volume (mount sementara)
docker run --rm -v pgdata:/data alpine ls -la /data
Masalah Umum dan Solusinya
Container tidak bisa resolve nama container lain:
Pastikan kedua container di network yang sama. Gunakan docker network inspect untuk verifikasi.
Data hilang setelah rebuild: Pastikan path yang di-mount volume benar. Typo di path mount adalah penyebab paling sering.
Permission error pada bind mount:
Tambahkan user mapping di Dockerfile atau gunakan flag :z untuk SELinux.
# Fix permission
docker run -v ./data:/app/data:z my-app
Cleanup: Membersihkan Resource
Seiring waktu, volume dan network yang tidak terpakai menumpuk. Bersihkan secara berkala:
# Hapus volume yang tidak dipakai container manapun
docker volume prune
# Hapus network yang tidak dipakai
docker network prune
# Nuclear option: hapus semua yang tidak terpakai
docker system prune --volumes
Peringatan: docker system prune --volumes akan menghapus SEMUA volume yang tidak sedang dipakai. Pastikan tidak ada data penting sebelum menjalankan command ini.
Kesimpulan
Docker network dan volume adalah fondasi environment development yang solid. Network custom memberikan DNS resolution otomatis antar container. Volume memastikan data persist dan performa tetap optimal.
Tiga hal yang perlu diingat:
- Selalu gunakan custom bridge network — jangan andalkan default bridge
- Pilih jenis volume yang tepat — bind mount untuk source code, named volume untuk data dan dependency
- Perhatikan cleanup — jalankan
prunesecara berkala agar disk tidak penuh
Dengan setup yang benar, kamu bisa fokus coding tanpa pusing soal environment. Cukup docker compose up -d dan langsung kerja.