Volume & Network #
Volume dan network adalah dua konsep fundamental yang menentukan bagaimana container menyimpan data dan berkomunikasi. Docker Compose menyediakan cara deklaratif untuk mengelola keduanya, sehingga kamu bisa fokus pada aplikasi, bukan infrastruktur.
Artikel ini membahas semua jenis volume yang didukung Compose, topologi network yang tersedia, dan best practice untuk setup yang bersih.
Volume di Docker Compose #
Volume adalah mekanisme untuk menyimpan data di luar container. Ada tiga jenis utama: named volume, bind mount, dan tmpfs.
Named Volume #
Named volume di-manage oleh Docker, disimpan di /var/lib/docker/volumes/, dan portable antar host.
services:
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Pada contoh di atas, db-data adalah named volume. Docker membuatkannya otomatis (atau pakai yang sudah ada) dan mount ke /var/lib/postgresql/data di container db.
Karakteristik named volume:
- Dikelola Docker — lifecycle, lokasi, dan cleanup di-manage oleh Docker.
- Portable — bisa di-backup, di-restore, di-move antar host.
- Aman untuk production — tidak bergantung pada layout filesystem host.
- Bisa di-share antar service dengan me-mount volume yang sama.
Inspect named volume:
# List semua volume
docker volume ls
# Inspect volume tertentu
docker volume inspect myproject_db-data
# Lihat dimana data disimpan
docker volume inspect --format '{{ .Mountpoint }}' myproject_db-data
# Output: /var/lib/docker/volumes/myproject_db-data/_data
Bind Mount #
Bind mount me-mount direktori atau file dari host langsung ke dalam container.
services:
web:
volumes:
- ./html:/usr/share/nginx/html:ro
- /opt/configs/app:/etc/app:ro
Format: host_path:container_path:options.
Karakteristik bind mount:
- Tergantung path host — harus ada di setiap host tempat stack dijalankan.
- Performa native — akses langsung ke filesystem host, tidak ada layer abstraksi.
- Cocok untuk development — source code di host bisa diedit dan langsung terlihat di container.
- Tidak portable — struktur direktori host harus sama.
Untuk development:
services:
api:
build: ./api
volumes:
- ./api/src:/app/src # hot reload
- ./api/tests:/app/tests
Perubahan kode di host langsung terlihat di container. Untuk bahasa interpreted (Python, JavaScript, Ruby), ini artinya tidak perlu rebuild image.
Hati-hati permission. File di host mungkin di-own oleh user host, tapi di container di-own oleh user container. Untuk menghindari permission issue:
services:
api:
user: "1000:1000" # samakan UID/GID dengan host
volumes:
- ./src:/app/src
Atau set permission di Dockerfile:
RUN chown -R 1000:1000 /app
tmpfs Mount #
tmpfs menyimpan data di memory (RAM), bukan disk. Data hilang saat container berhenti.
services:
api:
tmpfs:
- /tmp:size=100m
- /run
Karakteristik tmpfs:
- Sangat cepat — RAM access.
- Ephemeral — data hilang saat container stop/restart.
- Tidak di-share antar container — masing-masing punya tmpfs sendiri.
- Cocok untuk cache, session, file temporary processing.
Performance comparison: tmpfs (RAM) > local volume (SSD) > bind mount (host FS) > network volume (NFS/EFS). Pilih sesuai kebutuhan performa dan persistence.
Volume Driver #
Named volume mendukung driver untuk backend storage yang berbeda.
volumes:
db-data:
driver: local
driver_opts:
type: nfs
o: addr=10.0.0.5,rw
device: ":/path/to/dir"
shared-data:
driver: aws/efs
driver_opts:
efs.id: fs-12345678
Driver yang umum:
- local — default, simpan di host local.
- nfs — Network File System, shared storage.
- aws/efs — AWS Elastic File System.
- gcs — Google Cloud Storage (FUSE).
- azurefile — Azure File Storage.
Network volume driver (NFS, EFS) menambah latency dan potensi failure point. Untuk database production, lebih baik local SSD dengan replication di level aplikasi.
Network di Docker Compose #
Compose otomatis membuat network internal dan mendaftarkan semua service di dalamnya. Service bisa saling komunikasi via hostname = nama service.
Default Network #
Saat kamu tidak mendefinisikan network, Compose membuat satu network default.
services:
api:
image: myapi
db:
image: postgres:16
Docker membuat network myproject_default dan kedua service join ke sana. api bisa resolve db via hostname.
Inspect:
docker network ls
docker network inspect myproject_default
Custom Network #
Untuk kontrol lebih, definisikan network eksplisit.
services:
nginx:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
driver: bridge
Pada konfigurasi ini:
nginxdanapiada difrontend. Mereka bisa komunikasi.apidandbada dibackend. Mereka bisa komunikasi.dbtidak ada difrontend, jadinginxtidak bisa langsung aksesdb.- Semua harus lewat
api.
Ini adalah pattern defense in depth — pisahkan service publik dari service internal.
Network Driver #
Default driver untuk custom network di Compose adalah bridge. Driver lain juga tersedia.
networks:
frontend:
driver: bridge
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-backend
attachable: true
bridge driver di Linux menggunakan bridge interface di kernel. driver_opts memungkinkan konfigurasi tingkat lanjut.
Driver lain:
host— share network namespace dengan host. Tidak ada network isolation.overlay— untuk multi-host (Swarm mode).macvlan— assign MAC address ke container, terlihat sebagai device fisik.
Untuk Compose single host,bridgesudah cukup. Driver lain dibutuhkan untuk kasus khusus:hostuntuk performance network-sensitive,overlayuntuk multi-host (Swarm),macvlanuntuk integrasi dengan network fisik.
Network Aliases #
Service bisa punya beberapa hostname di network.
services:
api:
networks:
frontend:
aliases:
- api-service
- myapi
- backend-api
api sekarang bisa di-reach via api, api-service, myapi, atau backend-api di network frontend. Berguna untuk compatibility dengan kode lama yang hardcode hostname tertentu.
External Network #
Untuk menghubungkan stack Compose dengan resource di luar Compose.
services:
api:
networks:
- shared-network
networks:
shared-network:
external: true
name: my-existing-network
Network my-existing-network sudah ada di Docker (dibuat manual atau oleh stack lain). Compose tidak akan menghapusnya saat down.
Use case:
- Stack yang dibagi antar multiple Compose project.
- Network monitoring atau logging yang berdiri sendiri.
- Service legacy yang di-manage di luar Compose.
Contoh Setup Lengkap #
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
- html:/usr/share/nginx/html
networks:
- frontend
depends_on:
- api
restart: unless-stopped
api:
build: ./api
environment:
- DATABASE_URL=postgres://app:secret@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
networks:
- frontend
- backend
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=app
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=myapp
volumes:
- pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
restart: unless-stopped
cache:
image: redis:7-alpine
volumes:
- cache-data:/data
networks:
- backend
restart: unless-stopped
worker:
build: ./worker
environment:
- DATABASE_URL=postgres://app:secret@db:5432/myapp
networks:
- backend
restart: unless-stopped
volumes:
pg-data:
cache-data:
html:
networks:
frontend:
backend:
internal: false # expose ke host? atau biarkan false
Stack ini punya 5 service, 3 named volume, 2 network. Database dan cache di-isolate di backend. Hanya nginx yang di-expose ke host via ports.
Best Practice #
Gunakan Named Volume untuk Data #
Named volume adalah default yang aman. Ia portable, di-manage Docker, dan mendukung backup.
# BAGUS
volumes:
- db-data:/var/lib/postgresql/data
# HINDARI untuk production
volumes:
- /var/lib/postgresql/data:/var/lib/postgresql/data
Bind mount ke absolute path di host rapuh — kalau host berbeda layout, container gagal start.
Bind Mount untuk Development #
Untuk development, bind mount source code biar hot-reload jalan.
# docker-compose.dev.yml
services:
api:
volumes:
- ./src:/app/src # hot reload
- /app/node_modules # exclude dari bind mount
/app/node_modules di-mount sebagai anonymous volume untuk mencegah host’s node_modules (kalau ada) override container’s.
Pisahkan Network Sesuai Peran #
networks:
public: # di-expose ke internet
internal: # service-to-service only
management: # monitoring, debugging
Pisahkan network berdasarkan siapa yang boleh akses. Database jangan pernah di public network.
Set Resource Limits #
Untuk container yang mount banyak data atau share network besar.
services:
db:
volumes:
- db-data:/var/lib/postgresql/data
deploy:
resources:
limits:
memory: 4G
Backup Volume #
Pakai container terpisah untuk backup.
# Backup volume ke file
docker run --rm \
-v myproject_pg-data:/source:ro \
-v $(pwd)/backups:/backup \
alpine tar -czf /backup/pg-data-$(date +%F).tar.gz -C /source .
# Restore dari file
docker run --rm \
-v myproject_pg-data:/target \
-v $(pwd)/backups:/backup:ro \
alpine tar -xzf /backup/pg-data-2024-01-15.tar.gz -C /target
Clean separation: data via volume, service via Compose, backup via separate container. Ini memungkinkan backup tanpa mengganggu service, dan service bisa di-recreate tanpa kehilangan data.
Tabel Referensi Volume Mount #
Referensi cepat untuk semua cara mount volume di Compose.
| Tipe | Syntax | Contoh |
|---|---|---|
| Named volume | name:path |
db-data:/var/lib/data |
| Named volume (eksplisit) | type:volume,source:...,target:... |
Long form |
| Bind mount | host:path:container:path |
./src:/app/src |
| Bind mount (eksplisit) | type:bind,source:...,target:... |
Long form |
| tmpfs (shorthand) | - /tmp |
- /tmp |
| tmpfs (eksplisit) | type:tmpfs,target:... |
Long form |
| Anonymous volume | - /var/lib/data |
- /var/lib/data |
Contoh long-form syntax:
volumes:
# Named volume
- type: volume
source: db-data
target: /var/lib/postgresql/data
# Bind mount dengan read-only
- type: bind
source: ./configs
target: /etc/app/configs
read_only: true
# tmpfs dengan size limit
- type: tmpfs
target: /tmp
tmpfs:
size: 100m
Long-form berguna untuk opsi yang tidak ada di shorthand, seperti bind propagation, tmpfs.size, atau volume nocopy.
Tabel Referensi Network #
| Tipe | Syntax | Contoh |
|---|---|---|
| Default network | (otomatis) | Otomatis dibuat |
| Custom network | name: ... di top-level |
frontend: ... |
| External network | external: true |
external: true, name: my-net |
| Network dengan driver | driver: ... |
driver: bridge |
| Network dengan subnet | ipam: ... |
ipam: { config: [...] } |
Network dengan static IP:
networks:
backend:
ipam:
driver: default
config:
- subnet: 10.5.0.0/16
services:
db:
networks:
backend:
ipv4_address: 10.5.0.5
Berguna untuk service yang butuh IP tetap — biasanya untuk legacy yang hardcode IP.
Volume Lifecycle Management #
Prune Unused Volumes #
# Hapus volume yang tidak di-mount ke container manapun
docker volume prune
# Hapus semua volume yang tidak ada di Compose file
docker compose down --volumes
docker compose down --volumes menghapus semua volume yang dideklarasikan di Compose file. Lebih aman dari docker volume prune --all.
Backup Strategy #
Backup harus jadi bagian dari operational routine. Contoh script untuk Postgres:
#!/bin/bash
BACKUP_DIR="/backups/$(date +%F)"
mkdir -p "$BACKUP_DIR"
# Backup database dengan pg_dump
docker compose exec -T db pg_dump -U app myapp | gzip > "$BACKUP_DIR/db.sql.gz"
# Backup raw volume (untuk file-based data, bukan database)
docker run --rm \
-v myproject_pg-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar -czf /backup/pg-data.tar.gz -C /source .
# Upload ke S3
aws s3 sync "$BACKUP_DIR" "s3://my-backups/$(date +%F)/"
Test restore procedure secara berkala — backup yang tidak pernah di-restore tidak ada gunanya.
Untuk database, pakaipg_dump/mysqldumpdaripada copy volume langsung. Database punya internal state (WAL, redo log, dll) yang harus konsisten.pg_dumpmemastikan snapshot yang konsisten. Copy raw volume bisa menghasilkan backup yang corrupt.
Migration Volume #
Untuk pindah volume antar host atau cloud.
# Stop service yang pakai volume
docker compose stop db
# Export volume ke file
docker run --rm \
-v myproject_pg-data:/from:ro \
-v $(pwd):/to \
alpine tar -czf /to/pg-data.tar.gz -C /from .
# Transfer file ke host baru (scp, rsync, dll)
rsync -avz pg-data.tar.gz user@newhost:/tmp/
# Di host baru, import
docker volume create pg-data
docker run --rm \
-v pg-data:/to \
-v /tmp:/from:ro \
alpine tar -xzf /from/pg-data.tar.gz -C /to
# Start service di host baru
docker compose up -d db
Network Performance Tuning #
MTU dan Driver #
Default MTU untuk bridge network adalah 1500. Untuk network dengan encapsulation overhead (overlay, VXLAN), kamu mungkin perlu turunkan.
networks:
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.mtu: 1450
DNS Resolution #
Compose otomatis setup DNS untuk service di network. Resolution terjadi via Docker’s embedded DNS server.
# Test DNS resolution dari dalam container
docker compose exec api nslookup db
docker compose exec api nslookup redis
Jika nslookup gagal, biasanya ada masalah dengan network setup atau service tidak di network yang sama.
Connection Limits #
Untuk high-traffic service, tune ulimits (file descriptor).
services:
api:
ulimits:
nofile:
soft: 65536
hard: 65536
Atau tune sysctl dalam container (kalau image mendukung):
services:
api:
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_max_syn_backlog=1024
Default network Compose cukup untuk kebanyakan kasus. Tuning MTU, ulimits, dan sysctls adalah optimasi untuk high-performance workload. Untuk development dan small production, default sudah lebih dari cukup.
Recap Cheatsheet #
| Aspek | Rekomendasi |
|---|---|
| Data persisten | Named volume |
| Source code di host | Bind mount |
| Cache ephemeral | tmpfs |
| Network default | Otomatis |
| Multi-tier isolation | Custom network per peran |
| Backup | Container terpisah + upload ke S3 |
| Prune | docker compose down --volumes |
| Production driver | local (SSD) atau managed DB |
Ringkasan #
- Volume adalah cara Docker menyimpan data di luar container. Tiga jenis: named volume, bind mount, tmpfs.
- Named volume adalah default yang aman — portable, di-manage Docker, support backup. Gunakan untuk data persisten (database, upload).
- Bind mount untuk development (source code hot-reload) atau konfigurasi yang perlu akses langsung dari host. Hindari untuk production karena tidak portable.
- tmpfs untuk data ephemeral di memory. Sangat cepat tapi hilang saat restart.
- Network di Compose otomatis dibuat. Service di file yang sama bisa saling resolve via hostname.
- Custom network untuk pisahkan service sesuai peran (public, internal, management). Defense in depth.
- Network driver
bridgeuntuk single host.overlayuntuk multi-host (Swarm).hostuntuk performance.- Aliases untuk multiple hostname di satu network. External network untuk integrasi dengan resource di luar Compose.
- Backup volume via container terpisah. Restore juga via container, bukan langsung edit di host.
- Best practice: named volume untuk data, bind mount untuk development code, pisahkan network per peran, set resource limits, dan punya backup strategy.