Kita baru saja menutup Chapter Tmpfs Mount dengan tiga jenis mount yang seluruhnya sudah pernah kita pegang: volume data-web yang menyimpan halo.txt, bind mount yang menjembatani direktori /home/budi/situs ke dalam container, dan tmpfs yang isinya lenyap begitu container berhenti. Penutup chapter itu menitipkan satu janji: kerangka memilih akan diuji dengan skenario demi skenario, termasuk kasus yang memakai ketiga jenis mount sekaligus dalam satu deployment. Pertanyaannya kini bergeser dari “bagaimana cara memakainya” menjadi “mana yang harus dipilih” — dan ini bukan pertanyaan akademik, karena pilihan yang salah langsung terasa di dunia nyata: data database yang hilang bersama container yang dihapus, alur edit-uji yang tersendat karena source code tersalin ke dalam image, atau secret yang tercecer di disk padahal seharusnya hanya hidup di memori. Chapter ini menyusun kerangka keputusannya — tabel delapan dimensi, alur tiga pertanyaan, dan tiga skenario nyata — supaya kita bisa memilih dalam hitungan detik, bukan dengan menebak-nebak; janji tentang deployment yang memakai ketiga jenis mount sekaligus itu sendiri akan kita tepati pada Chapter Mount Read-Only.
Tiga Jenis Mount dalam Satu Tabel #
Ketiga jenis mount terasa mirip karena semuanya menampilkan berkas di dalam container, tetapi mekanisme di baliknya berbeda total. Tabel berikut membandingkan ketiganya dari delapan dimensi yang paling sering menentukan keputusan di lapangan:
| Dimensi | Volume | Bind Mount | Tmpfs Mount |
|---|---|---|---|
| Lokasi fisik data | Area khusus Docker di disk host, misalnya /var/lib/docker/volumes/<nama>/_data | Path apa pun di host yang kita tunjuk sendiri | RAM host, tidak pernah menulis ke disk |
| Dikelola oleh | Docker daemon sepenuhnya, dari pembuatan sampai penghapusan | Kita sendiri, Docker hanya menjembatani path yang kita pilih | Kernel Linux lewat filesystem tmpfs |
| Portabilitas lintas host | Tinggi — data berpindah lewat pola backup-restore tanpa peduli struktur direktori host | Rendah — host baru harus menyiapkan struktur path yang sama persis | Tidak relevan — data memang tidak dirancang berpindah |
| Kemudahan backup | Mudah — pola helper container resmi mengarsipkan isi volume | Mudah — berkasnya berkas host biasa untuk tool backup apa pun | Tidak perlu dibackup — isi hilang saat container berhenti |
| Kinerja tulis berat | Baik — penulisan langsung ke filesystem host tanpa lapisan tambahan | Baik di Linux; melambat di Docker Desktop karena menembus lapisan berbagi berkas VM | Sangat cepat karena di RAM, tetapi memakan memori dan batas ukurannya kecil |
Persisten setelah docker rm | Ya — volume tetap berdiri sampai docker volume rm | Ya — berkas memang milik host sejak awal | Tidak — hilang begitu container berhenti |
| Use case ideal | Database, state aplikasi, data yang dibagi antar container | Konfigurasi produksi, source code saat pengembangan, berkas referensi | Secret sementara, cache antar-langkah, data sensitif sekali pakai |
| Dukungan platform | Linux, macOS, Windows | Linux, macOS, Windows | Hanya kernel Linux; Docker Desktop menyediakannya lewat VM Linux-nya |
Mari kita telaah dimensi-dimensi yang paling sering menentukan keputusan:
- Kolom “dikelola oleh” adalah akar dari hampir semua perbedaan lain. Volume hidup di wilayah yang dikuasai Docker, sehingga Docker pula yang menjamin pola pendataan, backup, dan pembersihannya; bind mount hidup di wilayah kita, sehingga Docker tidak tahu apa-apa tentang isi path itu dan hanya menyediakan jembatan.
- Kolom “portabilitas lintas host” menentukan nasib aplikasi saat pindah server. Volume bisa dibungkus menjadi arsip dan dituangkan kembali di host mana pun; bind mount mengikat kita pada struktur direktori host — path
/home/budi/situstidak berarti apa pun di host baru dengan nama user berbeda. - Kolom “kinerja tulis berat” sering diabaikan sampai database berat mulai tersendat. Di Linux, volume dan bind mount sama-sama menulis langsung ke filesystem host; di macOS dan Windows, bind mount harus menembus lapisan berbagi berkas antara host dan VM Linux di dalam Docker Desktop, dan penulisan berkas kecil yang sangat sering adalah pola paling menderita dalam skenario itu.
- Kolom “persisten setelah
docker rm” mengingatkan pelajaran Chapter Konsep Persistence: yang menentukan umur data bukan container, melainkan jenis mount yang menampungnya — hanya volume dan bind yang sanggup melampauidocker rm, sementara tmpfs sengaja dibuat sebaliknya.
Alur Keputusan #
Delapan dimensi di atas tersaring menjadi tiga pertanyaan berurutan yang bisa kita lalui dalam hitungan detik. Diagram berikut memetakan alurnya:
Diagram tanpa penjelasan hanya setengah keputusan, jadi mari kita telaah empat langkahnya satu per satu:
- Langkah pertama — tanya umur data. Bila data harus bertahan melewati
docker rm— database, unggahan pengguna, log penting — kita masuk cabang kiri; bila tidak, cabang kanan menunggu. Pertanyaan ini adalah versi ringkas dari seluruh Chapter Konsep Persistence. - Langkah kedua — tanya siapa pemilik sah berkasnya. Data yang harus bertahan masih terbelah dua: berkas yang memang sudah hidup dan diedit di host (source code yang kita utak-atik di editor, konfigurasi yang dikelola tool host) jatuh ke bind mount; data yang lahir dari aplikasi di dalam container dan tidak punya alasan hidup di path host tertentu jatuh ke volume.
- Langkah ketiga — tanya sifat datanya. Data yang tidak perlu bertahan dan bersifat sementara atau sensitif — token sekali pakai, hasil antar-langkah, berkas yang tidak boleh menyentuh disk — adalah wilayah tmpfs; setelah container berhenti, tidak ada jejak yang perlu dibersihkan.
- Langkah keempat — jatuh ke writable layer. Bila semua pertanyaan terjawab “tidak”, data memang boleh hidup dan mati bersama container di writable layer yang kita bedah pada Chapter Writable Container Layer; ini bukan pilihan buruk, melainkan pilihan tepat untuk data yang benar-benar sekali pakai.
Hasil alur tersebut diringkas menjadi tabel keputusan sehari-hari berikut:
| Situasi | Pilihan | Alasan ringkas |
|---|---|---|
| Data penting, lahir dari aplikasi container | Volume | Persisten, dikelola Docker, mudah dibackup dan dipindah |
| Source code atau konfigurasi yang diedit di host | Bind mount | Perubahan host langsung terlihat container tanpa menyalin ulang |
| Data sementara atau sensitif sekali pakai | Tmpfs mount | Hidup di RAM, tidak menyentuh disk, lenyap saat berhenti |
| Data sekali pakai yang tidak sensitif | Writable layer | Ikut umur container, tanpa biaya pengelolaan |
Rekomendasi Resmi #
Dokumentasi Docker sendiri tidak membiarkan kita mengarang aturan sendiri: gunakan volume untuk data persisten pada umumnya, gunakan bind mount untuk berbagi konfigurasi atau source code dari host ke container — terutama saat pengembangan — dan gunakan tmpfs untuk data sementara yang tidak boleh bertahan, termasuk data sensitif. Rekomendasi ini bukan selera, melainkan konsekuensi dari tabel delapan dimensi di atas: volume menang pada portabilitas, backup, dan kinerja tulis untuk data aplikasi, sementara bind mount menang justru pada dimensi yang tidak dimiliki volume — berbagi berkas yang sudah ada dan sedang diedit di host.
Tiga Skenario Nyata #
Tabel dan diagram baru benar-benar melekat setelah kita melihatnya bekerja. Tiga skenario berikut memakai ketiga jenis mount dalam keadaan yang paling sering kita temui di pekerjaan nyata.
Skenario 1 — Database Produksi dengan Volume #
Skenario pertama adalah keputusan yang paling mahal apabila salah: database produksi. Budi menaikkan PostgreSQL untuk aplikasi internal kantornya, dan datanya wajib bertahan melewati apa pun yang terjadi pada container — patch image, restart, bahkan penghapusan. Volume pgdata peninggalan Chapter Volume masih setia menunggu, jadi keputusan memilih volume tinggal dieksekusi:
$ docker run -d --name db \
-e POSTGRES_PASSWORD=rahasia123 \
-v pgdata:/var/lib/postgresql/data \
postgres:18-alpineOutput yang Dihasilkan:
678d6406c1dc061313cd0e9770c8024a48f5f4df06b476233a45b8e93228e1eeSetelah database siap — hanya beberapa detik karena direktori datanya sudah terisi — Budi membuktikan bahwa engine hidup dan volumenya tercatat:
$ docker exec db pg_isready -U postgresOutput yang Dihasilkan:
/var/run/postgresql:5432 - accepting connections$ docker volume lsOutput yang Dihasilkan:
DRIVER VOLUME NAME
local data-web
local latihan-volume
local pgdatadata-web dan latihan-volume adalah kenalan dari chapter-chapter sebelumnya. Sekarang ujian yang paling meyakinkan justru tidak membutuhkan ritual apa pun — kita intip isi database-nya langsung:
$ docker exec db psql -U postgres -c "\dt"Output yang Dihasilkan:
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | peserta | table | postgres
(1 row)Mari kita telaah rangkaian bukti di atas:
-v pgdata:/var/lib/postgresql/data— volume bernama dipasang tepat di direktori data image postgres, sehingga seluruh penulisan engine mendarat di volume, bukan di writable layer.- Output langsung ID tanpa baris pull — image
postgres:18-alpinesudah lokal sejak Chapter Volume; inisialisasi ulang juga dilewati karena direktori data di volume sudah terisi, itulah sebabnya container siap dalam hitungan detik. \dtmenemukan tabelpeserta— tabel itu lahir pada Chapter Volume di tangan containerdb-latihanyang sudah lama dihapus; datanya terus hidup dipgdatadan langsung dikenali container baru ini tanpa satu langkah pemulihan. Persistensi yang dulu kita buktikan lewat ritual hapus-lalu-jalankan-ulang kini bekerja begitu saja.- Pilihan volume di sini sekaligus pintu perawatan data — volume bernama mudah dirujuk di
docker volume ls, mudah diaudit, dan mudah dibekukan menjadi arsip cadangan lewat pola helper container pada Chapter Backup dan Restore Volume.
Skenario 2 — Situs Dev dengan Bind Mount Read-Only #
Skenario kedua adalah keseharian pengembangan: situs statis yang sedang dipoles di editor. Direktori /home/budi/situs — bekas arena latihan Chapter Bind Mount yang halamannya terakhir berisi versi 2 — masih setia menunggu di host, dan berkas-berkasnya memang sudah hidup serta terus diedit dari host, sehingga bind mount adalah pilihan alurnya. Karena container nginx kali ini hanya perlu membaca, Budi menambahkan suffix :ro yang akan kita bedah tuntas pada Chapter Mount Read-Only:
$ docker run -d --name web-dev \
-p 8081:80 \
-v /home/budi/situs:/usr/share/nginx/html:ro \
nginx:1.29-alpineOutput yang Dihasilkan:
Unable to find image 'nginx:1.29-alpine' locally
1.29-alpine: Pulling from library/nginx
...
Digest: sha256:4f2c9d8e7a1b...
Status: Downloaded newer image for nginx:1.29-alpine
f2b3d0fa9374ef3efb78330c3094cef358dcdd395bfeb66837c6e6343d3088d5Keunggulan khas bind mount ini sudah kita saksikan pada Chapter Bind Mount — perubahan di host terlihat seketika tanpa membangun ulang apa pun — dan kali ini kita menikmatinya dengan container yang terkunci:
$ curl localhost:8081Output yang Dihasilkan:
<h1>versi 2</h1>$ echo '<h1>versi 3</h1>' > /home/budi/situs/index.html
$ curl localhost:8081Output yang Dihasilkan:
<h1>versi 3</h1>Mari kita telaah mengapa alur ini layak mendapat bind mount:
-v /home/budi/situs:/usr/share/nginx/html:ro— direktori host dijembatani ke akar dokumen nginx; setiap penyimpanan di editor langsung menjadi isi situs, tanpadocker builddan tanpa pembuatan container ulang.curlpertama menyambutversi 2— halaman itu adalah warisan utuh dari latihan Chapter Bind Mount; bind mount memang membawa berkas apa adanya, bukan salinan segar.- Suffix
:romenjaga arah aliran — satu arah dari host ke container: editor kita menulis, nginx hanya membaca, sehingga proses di dalam container tidak akan pernah merusak source yang sedang dipoles; detail perilakunya kita bedah tuntas pada Chapter Mount Read-Only.
Skenario 3 — API Key untuk Batch Job dengan Tmpfs #
Skenario ketiga milik pekerjaan tengah malam: batch job yang membutuhkan API key untuk membaca layanan eksternal. Kredensial tidak boleh menetap di disk — tidak di image, tidak di writable layer — sehingga tmpfs adalah satu-satunya kandidat, dengan mode direktori yang dikunci untuk pemiliknya saja:
$ docker run --rm \
--mount type=tmpfs,destination=/run/secret,tmpfs-mode=1700 \
-e API_KEY=rahasia123 \
alpine:3.20 \
sh -c 'umask 077; printf "%s" "$API_KEY" > /run/secret/api.key && ls -l /run/secret && cat /run/secret/api.key'Output yang Dihasilkan:
total 4
-rw------- 1 root root 10 Oct 13 15:18 api.key
rahasia123Kita periksa juga mode direktorinya sendiri:
$ docker run --rm \
--mount type=tmpfs,destination=/run/secret,tmpfs-mode=1700 \
alpine:3.20 ls -ld /run/secretOutput yang Dihasilkan:
drwx------T 2 root root 40 Oct 13 15:19 /run/secretMari kita telaah kedua hasil di atas:
tmpfs-mode=1700— angka7memberirwxkepada pemilik direktori, dua angka0menghapus seluruh hak grup dan pihak lain, sementara angka1di depan memasang sticky bit: berkas di dalamnya hanya bisa dihapus pemiliknya, pola yang sama dengan/tmpsistem Linux pada umumnya.-e API_KEY=rahasia123— kredensial masuk lewat environment variable, lalu dituangkan ke berkas di tmpfs denganumask 077sehingga berkasnya terkunci mode600; aplikasi batch tinggal membaca/run/secret/api.keyseperti membaca berkas biasa.--rmmenutup kisahnya sendiri — begitu batch job selesai, container dihapus, tmpfs ikut terlepas dari memori, dan tidak ada jejakrahasia123di disk mana pun; inilah sifat yang membuat tmpfs pantas menyimpan data sensitif sekali pakai.- Bentuk
--mount— skenario ini sengaja memakai bentuk panjang--mount type=tmpfs,...karena opsitmpfs-modehanya tersedia di sana; hasil yang sama sebenarnya bisa dicapai lewat flag--tmpfs, materi yang sudah kita bahas pada Chapter Tmpfs Mount.
Sebelum melangkah, kita rapikan mesin latihan agar bab-bab berikutnya mulai dari keadaan yang terkendali. Container db dan web-dev sudah menuntaskan tugas peragaannya:
$ docker rm -f db web-devOutput yang Dihasilkan:
db
web-devVolume pgdata, volume data-web, dan direktori /home/budi/situs sengaja kita biarkan — volume produksi memang tidak dibuang hanya karena latihan selesai, dan ketiganya masih menjadi bahan cerita pada chapter-chapter berikutnya. Volume memang begitu: sekali dipilih untuk data penting, ia setia menunggu sampai diminta lagi.
Dari tiga skenario tadi terlihat satu pola yang belum kita kunci: hampir semua mount yang kita pasang masih terbuka untuk ditulis oleh container — suffix :ro pada skenario situs baru selangkah menjadi kebiasaan. Bagaimana jika kita ingin melindungi data dari container itu sendiri, menjadikannya benar-benar hanya-baca bagi proses di dalamnya, bahkan mengunci seluruh akar filesystem container? Itu pekerjaan suffix :ro dan flag --read-only, materi Chapter Mount Read-Only.
Referensi #
- Storage di Docker Engine — halaman induk konsep penyimpanan dan peta tiga jenis mount.
- Volumes — rekomendasi resmi volume untuk data persisten.
- Bind Mounts — panduan bind mount untuk konfigurasi dan source code.
- Tmpfs Mounts — panduan tmpfs untuk data sementara dan sensitif.