Volume menempatkan data di wilayah yang dikelola penuh oleh Docker — nyaman untuk data persisten, tetapi kurang akrab bagi kita sebagai manusia yang bekerja di host. Bagaimana bila yang ingin kita pasang justru berkas milik kita sendiri: nginx.conf yang diedit di editor, direktori source code yang berubah tiap menit, atau folder yang sudah diawasi tool lain di host? Docker menjawab dengan bind mount: mekanisme mount yang membiarkan kita menunjuk path host apa pun dan memasangnya langsung ke dalam container. Chapter ini membedah cara kerjanya yang dua arah, kekuatan terbesarnya berupa live edit tanpa rebuild, dua jebakan klasiknya pada path yang belum ada dan pada berkas tunggal, sampai kekhasannya di Windows.
Jendela Dua Arah ke Filesystem Host #
Bind mount bekerja dengan prinsip paling sederhana dari ketiga jenis mount: kernel Linux memasang path di filesystem host ke path di dalam container, apa adanya. Tidak ada area khusus milik Docker, tidak ada salinan, tidak ada pra-isi — berkas yang dilihat proses di container dan berkas yang kita buka di host adalah benda yang sama. Konsekuensinya simetris: tulisan dari container langsung terlihat di host, dan suntingan kita di host langsung terlihat oleh container, tanpa jeda dan tanpa proses salin.
Mari kita buktikan dengan situs mini milik Budi. Di host, ia menyiapkan satu direktori berisi satu berkas:
$ mkdir -p /home/budi/situs
$ echo "<h1>versi 1</h1>" > /home/budi/situs/index.html
$ docker run -d --name web -p 8080:80 -v /home/budi/situs:/usr/share/nginx/html nginx
$ curl localhost:8080Output yang Dihasilkan:
f7c2a91b3e55913c4a5f1c6c0a4d8e2b3f4a5b6c7d8e9f0a1b2c3d4e5f60718a
<h1>versi 1</h1>Mari kita telaah susunan perintah dan hasilnya:
mkdirdanechoberjalan di host —/home/budi/situs/index.htmladalah berkas host biasa, dibuat sebelum container mana pun menyala.-v /home/budi/situs:/usr/share/nginx/html— bagian pertama kini path host, bukan nama volume; itulah pembeda bentuk antara bind mount dan volume pada flag-v.- Isi path image tidak dipra-isi —
/usr/share/nginx/htmlmilik image tertutup isi direktori host apa adanya; halaman selamat datang bawaan nginx tidak tampak karenaindex.htmlversi Budi yang kini berdiri di sana. curlmenyajikan berkas host — nginx di dalam container membaca berkas yang fisiknya tinggal di/home/budi/situs, tanpa satu byte pun tersalin ke writable layer.
Live Edit Tanpa Rebuild #
Kekuatan bind mount paling terasa pada perubahan. Budi menyunting berkasnya langsung di host — cukup dengan echo, tanpa menyentuh container:
$ echo "<h1>versi 2</h1>" > /home/budi/situs/index.html
$ curl localhost:8080Output yang Dihasilkan:
<h1>versi 2</h1>Perubahan tampil seketika: tidak ada docker build, tidak ada docker restart, bahkan tidak ada satu perintah Docker pun sejak container menyala. Bandingkan dengan alur image pada Section Dockerfile — setiap suntingan COPY menuntut build baru agar perubahannya masuk. Arah sebaliknya pun sama mulusnya:
$ docker exec web sh -c 'echo dibuat dari container > /usr/share/nginx/html/catatan.txt'
$ ls -l /home/budi/situsOutput yang Dihasilkan:
total 8
-rw-r--r-- 1 root root 22 Okt 13 14:25 catatan.txt
-rw-r--r-- 1 budi budi 17 Okt 13 14:23 index.htmlMari kita telaah apa yang dikatakan tabel berkas di atas:
catatan.txtlahir dari dalam container — proses yang dijalankandocker execberjalan di dalamweb, tetapi berkasnya muncul di direktori host: bind mount memang jendela dua arah.index.htmltetap milikbudi— berkas yang ditulis dari host membawa kepemilikan user host yang menulisnya.catatan.txttercatat milikroot— prosesdocker execbawaan berjalan sebagai root di dalam container, dan bind mount meneruskan kepemilikan numerik apa adanya: UID 0 di container adalah UID 0 di host Linux.- Beda pemilik pada satu folder adalah gejala klasik — UID numerik yang sama berlaku dua arah, dan pertemuan UID container dengan UID host inilah sumber konflik izin yang kita bedah tuntas pada Chapter Permission dan Ownership Volume.
Untuk alur development, kemampuan ini adalah fondasi: source code di host, aplikasi berjalan di container, dan setiap simpanan editor langsung terlihat tanpa build ulang. Tooling yang mengawasi perubahan berkas lalu memuat ulang aplikasi otomatis kita rangkai menjadi workflow lengkap pada Chapter Hot Reload di Section Docker dalam Pengembangan.
-v versus –mount untuk Bind Mount #
Kedua gaya penulisan dari Chapter Konsep Persistence berlaku juga untuk bind mount, dengan satu perbedaan perilaku yang penting diketahui sejak dini: nasib path host yang belum ada. Tabel berikut merangkumnya:
| Aspek | -v singkat | --mount panjang |
|---|---|---|
| Bentuk | -v /home/budi/situs:/usr/share/nginx/html | --mount type=bind,src=/home/budi/situs,dst=/usr/share/nginx/html |
| Path host belum ada | Membuat direktori baru secara otomatis | Menolak dengan galat yang jelas |
| Keterbacaan | Ringkas, akrab di terminal | Eksplisit — setiap bagian berlabel |
| Paling tepat untuk | Perintah cepat sebaris | Skrip dan dokumentasi yang menjaga diri |
Perbedaan perilaku itu layak disaksikan langsung. Pertama, --mount menolak keras saat path host ternyata belum ada — kita sengaja menulis situs-typo alih-alih situs:
$ docker run -d --name web-typo --mount type=bind,src=/home/budi/situs-typo,dst=/usr/share/nginx/html nginxOutput yang Dihasilkan:
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /home/budi/situs-typo.
See 'docker run --help'.Galat ini jujur: sumber bind tidak ada, container tidak dibuat, dan tidak ada yang berubah di host. Bentuk -v bersikap sebaliknya — ia diam-diam menyembunyikan masalahnya:
$ docker run -d --name web-typo -p 8082:80 -v /home/budi/situs-typo:/usr/share/nginx/html nginx
$ ls -ld /home/budi/situs-typo
$ curl localhost:8082Output yang Dihasilkan:
73160b858a8a94a5c2c1f05c82c24c4a1bea7e199af4b7afe869341064a5be51
drwxr-xr-x 2 root root 4096 Okt 13 14:35 situs-typo
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.29.4</center>
</body>
</html>Mari kita telaah rangkaian diam-diam ini:
- Direktori lahir sendiri — daemon membuat
/home/budi/situs-typosebagai direktori kosong milik root, lalu memasangnya; container menyala seolah semua beres. curlmendapat403 Forbidden— document root yang kosong membuat nginx menolak melayani direktori tanpa indeks; pengguna pemula kerap mendiagnosis ke arah yang salah padahal biang keroknya path typo.- Bila path yang dituju berkas,
-vtetap membuat direktori — bind berkas tunggal dengan nama yang belum ada melahirkan direktori bernama sama, bukan berkas; kejutannya lebih besar lagi.
Budi membereskan jejak latihan dengan docker rm -f web-typo, lalu membuang direktori situs-typo dengan sudo rmdir — direktori itu milik root, jadi penghapusannya juga butuh wewenang root. Sebelum lanjut, perlu diingat mengapa container web bisa memakai port 8080 sementara web-typo dialihkan ke 8082: dua container tidak boleh menerbitkan port host yang sama.
Kapan Memakai Bind Mount #
Tiga use case paling umum bind mount semuanya berakar pada satu sifat: berkas host dan berkas container adalah benda yang sama. Pertama, berkas konfigurasi: satu nginx.conf yang dikelola di host dipasang ke banyak container, sehingga perubahan konfigurasi terpusat tanpa membangun ulang image. Kedua, source code saat development: direktori proyek dipasang ke container yang menjalankan aplikasi, memangkas siklus edit-build-uji menjadi edit-uji — fondasi workflow Hot Reload. Ketiga, berbagi berkas dengan tool host lain: direktori yang diawasi backup host atau dipakai bersama tim bisa langsung dipasang tanpa menyalin.
Untuk data aplikasi seperti database, bind mount justru kurang tepat: letaknya melekat pada struktur direktori host tertentu, sulit dipindahkan antar mesin, dan detail permission-nya rentan konflik. Perbandingan lengkapnya:
| Aspek | Volume | Bind Mount |
|---|---|---|
| Pengelola | Docker daemon | Kita sendiri |
| Lokasi fisik | /var/lib/docker/volumes/... | Path host apa pun yang kita tunjuk |
| Backup | Pola helper container — Chapter Backup dan Restore Volume | Berkas host biasa, tinggal disalin |
| Portabilitas | Tinggi — nama dipakai ulang lintas host | Rendah — terikat struktur direktori host |
| Kegunaan khas | Database, data aplikasi | Konfigurasi, source code development |
Bind Berkas Tunggal #
Bind mount tidak terbatas direktori — satu berkas pun bisa dipasang, dan ini pola favorit untuk konfigurasi. Budi memakai salinan nginx.conf yang dulu ia ambil dengan docker cp pada Chapter Writable Container Layer, lalu memasangnya ke container terpisah:
$ mkdir -p /home/budi/konfigurasi
$ cp nginx.conf.host /home/budi/konfigurasi/nginx.conf
$ docker run -d --name web-konf -p 8081:80 -v /home/budi/konfigurasi/nginx.conf:/etc/nginx/nginx.conf nginx
$ docker exec web-konf nginx -tOutput yang Dihasilkan:
bc8e7a000fcc1a83c4530080a33b6bbc4d207890026ff4f72cafbeb21ab4a649
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulMari kita telaah pola ini:
- Satu berkas dipasang ke satu path berkas —
/etc/nginx/nginx.confdi dalam container kini menunjuk berkas di/home/budi/konfigurasi/nginx.conf; sisa image tetap utuh tanpa mount. nginx -tmemvalidasi konfigurasi dari dalam container — utilitas bawaan image membaca berkas yang sama yang Budi edit di host; hasilsyntax is okberlaku untuk keduanya.- Perubahan di host langsung terbaca — sama seperti direktori, isi berkas adalah benda yang sama di kedua sisi.
Satu catatan teknis penting untuk bind berkas tunggal: yang diikat kernel sebenarnya adalah inode berkasnya, bukan namanya. Editor yang menulis ulang berkas dengan membuat berkas baru lalu mengganti nama — perilaku bawaan banyak editor dan flag -i pada sed — menghasilkan inode baru, sementara container tetap memegang inode lama: suntingan kita tidak terlihat di dalam container sampai container dijalankan ulang. Bila ingin suntingan berkas tunggal selalu langsung terlihat, edit di tempat (menimpa isi berkas yang sama) atau restart container setelah menulis ulang.
Bind Mount di Windows dan Docker Desktop #
Di mesin Siti yang memakai Docker Desktop untuk Windows, bind mount tetap bekerja — berkas di C:\Users\Siti\situs tinggal dipasang ke container — dengan satu catatan jalur penulisan. Di PowerShell, path Windows ditulis apa adanya: -v C:\Users\Siti\situs:/usr/share/nginx/html langsung diterima karena argumen tidak diutak-atik. Di Git Bash, lapisan MSYS yang menerjemahkan argumen bergaya Unix menjadi path Windows justru menjadi biang kerok: path container seperti /usr/share/nginx/html ikut diterjemahkan menjadi path instalasi Git, dan mount berakhir salah alamat. Siti mengatasinya dengan prefiks ganda pada path hostnya:
$ docker run -d --name web-siti -p 8080:80 -v //c/Users/Siti/situs:/usr/share/nginx/html nginxOutput yang Dihasilkan:
691771b8d6d6bf970831fec3ed583d71c1a80167b2b37215d76b353b25cffe87Rapikan arena sebelum kita lanjut: docker rm -f web web-konf menghapus dua container latihan Budi, sementara di mesin Siti web-siti dibuang dengan docker rm -f web-siti. Volume dan bind mount kini sama-sama kita kuasai, dan keduanya berbagi satu sifat: data menumpang disk host. Padahal ada kelas data yang justru tidak boleh menyentuh disk sama sekali — cache yang boleh hilang kapan pun, atau kredensial yang tidak boleh meninggalkan jejak berkas. Untuk kelas itu Docker menyediakan mount yang tinggal di memori: tmpfs, materi Chapter tmpfs Mount.
Referensi #
- Bind Mounts
— mekanisme bind, perbedaan
-vdan--mount, serta perilaku path host yang belum ada. - docker run — CLI Reference
— definisi flag
-vdan--mountuntuk bind mount berkas maupun direktori. - nginx Documentation
— struktur
nginx.confdan validasi konfigurasi lewatnginx -t.