Chapter Writable Container Layer menutup dengan kesimpulan yang tidak bisa dinegosiasikan: data yang berharga tidak boleh tinggal di writable layer, karena satu docker rm sudah cukup menghapus semuanya. Pertanyaannya, seberapa nyata bahaya itu dalam praktik sehari-hari? Jawabannya paling terasa pada satu jenis beban kerja yang hampir semua tim miliki: database. Chapter ini membuka dengan kisah kehilangan data yang dialami Budi, membedah akar masalahnya pada konsep umur container versus umur data, lalu memetakan tiga jenis mount yang Docker sediakan sebagai jalan keluar — lengkap dengan kriteria memilih di antara ketiganya.
Kisah Budi: Database yang Lenyap Bersama Container #
Budi penasaran mencoba PostgreSQL versi 18 dalam wujud Alpine yang ramping. Ia menjalankan container baru dengan password contoh, persis pola yang biasa ia lihat di dokumentasi:
$ docker run -d --name db-latihan -e POSTGRES_PASSWORD=rahasia123 postgres:18-alpineOutput yang Dihasilkan:
18-alpine: Pulling from library/postgres
ce44d321fd03: Pull complete
b7c70e50ce6a: Pull complete
...
Digest: sha256:1b50fd69a38322b7f1e2f3f2c9a2f370703d5718b327738152775c8a89df45a2
Status: Downloaded newer image for postgres:18-alpine
docker.io/library/postgres:18-alpine
07179c852aa6a925b6f4cd33dfe63e68d4984074e8086437f52e211c6c5e2704Image terunduh untuk pertama kalinya — baris-baris layer dipotong karena cukup panjang — dan container db-latihan menyala. PostgreSQL membutuhkan beberapa detik untuk inisialisasi awal sebelum siap menerima koneksi; utilitas pg_isready bawaan image memberi kabar kapan waktunya tiba:
$ docker exec db-latihan pg_isready -U postgresOutput yang Dihasilkan:
/var/run/postgresql:5432 - accepting connectionsPenuh semangat, Budi membuat tabel latihan dan mengisinya dua baris data peserta:
$ docker exec db-latihan psql -U postgres -c "CREATE TABLE peserta (nama TEXT); INSERT INTO peserta VALUES ('Budi'), ('Siti');"Output yang Dihasilkan:
CREATE TABLE
INSERT 0 2$ docker exec db-latihan psql -U postgres -c "SELECT * FROM peserta;"Output yang Dihasilkan:
nama
------
Budi
Siti
(2 rows)Data tersimpan, koneksi berjalan, dan semuanya tampak sempurna. Beberapa jam kemudian Budi ingin mencoba konfigurasi memori yang berbeda, jadi ia mengulang pola lama yang ia kuasai dari Section Konfigurasi Container: buang container lama, jalankan yang baru — image-nya sama, jadi harusnya cepat saja:
$ docker rm -f db-latihan
$ docker run -d --name db-latihan -e POSTGRES_PASSWORD=rahasia123 postgres:18-alpine
$ docker exec db-latihan psql -U postgres -c "SELECT * FROM peserta;"Output yang Dihasilkan:
db-latihan
634f0093cbbe47ee6430207913ca9bd4498c839db7391dc8a7d118d5e2e26e57
ERROR: relation "peserta" does not exist
LINE 1: SELECT * FROM peserta;
^Mari kita telaah kejadian yang barusan menimpa Budi:
docker rm -f db-latihanberjalan tanpa galat — penghapusan container memang operasi sah dan sering; inilah yang membuat bahayanya licik.- Container baru menjalankan inisialisasi ulang — direktori data yang dilihat container baru masih kosong, jadi skrip entrypoint PostgreSQL menjalankan
initdbdari nol dan melahirkan cluster bersih tanpa tabelpeserta. - Data lama menumpang di writable layer container lama — seluruh direktori data fisik PostgreSQL tinggal di writable layer yang ikut terbuang pada baris pertama; persis batasan yang dipetakan pada Chapter Writable Container Layer.
- Tidak ada galat, tidak ada peringatan — Docker tidak menganggap ada yang salah, karena memang tidak ada: data aplikasi bukan urusan lifecycle container.
Sebelum melanjutkan, Budi merapikan arena dengan menghapus container keduanya melalui docker rm -f db-latihan. Pelajaran utamanya sudah terbentuk: umur container dan umur data adalah dua hal yang berbeda, dan menggabungkan keduanya di satu wadah adalah kesalahan desain. Yang Budi butuhkan adalah tempat menulis data yang sengaja dipisahkan dari container — dan Docker menyediakan tiga bentuknya.
Tiga Jenis Mount sebagai Jalan Keluar #
Mekanisme pemisahan umur di Docker bernama mount: sebuah lokasi penyimpanan di luar writable layer dipasang ke sebuah path di dalam container, sehingga tulisan ke path itu tidak lagi berakhir di layer yang lenyap bersama container. Ada tepat tiga jenis mount, dan ketiganya dibedakan oleh pertanyaan sederhana: di mana data secara fisik tinggal, dan siapa yang mengelolanya.
Jenis pertama adalah volume: penyimpanan yang diciptakan dan dikelola penuh oleh Docker di area khususnya sendiri, /var/lib/docker/volumes di disk host. Kita hanya berurusan dengan nama volume; daemon yang menentukan lokasi persisnya, memasangnya ke container, dan menjaganya tetap hidup setelah container mati. Jenis kedua adalah bind mount: kita sendiri menunjuk sebuah path di filesystem host — path apa pun yang kita mau — dan kernel Linux memasang path itu apa adanya ke dalam container. Jenis ketiga adalah tmpfs mount: data tidak pernah menyinggahi disk sama sekali, melainkan tinggal di memori host dan berakhir begitu container berhenti.
| Aspek | Volume | Bind Mount | tmpfs Mount |
|---|---|---|---|
Bentuk flag -v / singkat | -v nama-volume:/data | -v /path/host:/data | --tmpfs /data |
Bentuk --mount panjang | --mount type=volume,src=nama,dst=/data | --mount type=bind,src=/path/host,dst=/data | --mount type=tmpfs,destination=/data |
| Lokasi fisik data | Area khusus Docker di disk host | Path host apa pun yang kita tunjuk | Memori host, bukan disk |
| Pengelola | Docker daemon | Kita sendiri | Docker bersama kernel Linux |
| Umur data | Selamat dari docker rm | Selama berkasnya ada di host | Berakhir saat container berhenti |
| Portabilitas | Tinggi — nama dipakai ulang lintas container dan host | Rendah — bergantung struktur direktori host | Tidak relevan — isinya memang sementara |
| Kegunaan khas | Database, data aplikasi | Berkas konfigurasi, source code development | Cache, secret sementara |
Bentuk Eksplisit –mount #
Flag paling sering kita lihat di dokumentasi lama adalah -v, tetapi Docker juga menyediakan bentuk panjang --mount yang menuliskan setiap bagian secara eksplisit. Tiga jenis mount dibedakan lewat nilai type, sumber dinyatakan lewat src (alias source), dan tujuan di dalam container dinyatakan lewat dst (alias destination atau target). Bentuk umumnya:
--mount type=volume,src=<nama-volume>,dst=<path-di-container>
--mount type=bind,src=<path-di-host>,dst=<path-di-container>
--mount type=tmpfs,dst=<path-di-container>Perhatikan bahwa tmpfs tidak punya src — tidak ada sumber di disk untuk dipasang, karena isinya akan lahir dan mati di memori. Perbedaan gaya penulisan kedua bentuk tersebut dirangkum tabel berikut:
| Aspek | -v singkat | --mount panjang |
|---|---|---|
| Tata tulis | Satu string dipisah titik dua | Pasangan key=value dipisah koma |
| Keterbacaan | Ringkas dan cepat diketik | Eksplisit — setiap bagian berlabel |
| Perilaku pada path host yang belum ada | Membuat direktori otomatis | Menolak dengan galat yang jelas |
| Paling tepat untuk | Perintah cepat di terminal | Skrip, dokumentasi, dan berkas compose.yaml |
Satu catatan kecil tentang baris terakhir: berkas compose.yaml yang akan kita kenal pada Section Docker Compose memakai gaya penulisan panjang yang serumpun dengan --mount — biasakan membaca bentuk eksplisit sejak sekarang akan memudahkan transisi ke sana.
Ketiga jenis mount itu masing-masing mendapat chapter penuh di section ini. Volume kita bedah berikutnya: cara membuatnya, memeriksa isinya, dan membuktikan datanya selamat dari docker rm. Bind Mount menyusul setelahnya dengan kekuatan khasnya — perubahan di host langsung terlihat di container tanpa rebuild, fondasi alur kerja development. tmpfs Mount menutup trio dengan perannya menyimpan data yang justru tidak boleh bertahan: cache dan secret sementara. Dua chapter lanjutan melengkapi perawatan data berkelanjutan: pola mencadangkan dan memulihkan volume di Backup dan Restore Volume, serta pindah data antar host dan antar jenis mount di Migrasi Data Container.
Kriteria Memilih Jenis Mount #
Dengan tiga pilihan di tangan, keputusan sebaiknya tidak diambil berdasarkan kebiasaan, melainkan kriteria. Empat pertanyaan berikut menutup hampir semua kasus:
- Portabilitas — apakah data ini kelak harus berpindah host, atau dipakai container lain di mesin yang sama? Bila ya, volume adalah kandidat terkuat karena identitasnya hanyalah sebuah nama, bukan path di host tertentu.
- Backup — bagaimana data ini dicadangkan secara rutin? Volume punya pola pencadangan yang teruji lewat container bantu, materi Backup dan Restore Volume; bind mount dicadangkan seperti berkas host biasa, yang praktis justru bila sudah ada infrastruktur backup host.
- Performa — bagaimana pola tulis aplikasinya? Database menulis secara acak dan intensif, dan volume menghindari biaya copy-on-write yang membebani writable layer; beban seperti ini tidak boleh menumpang writable layer.
- Kepemilikan berkas — siapa pemilik numerik berkasnya di host dan di container? Bind mount mempertemukan UID/GID host dengan UID/GID container secara langsung, dan pertemuan ini kerap melahirkan konflik izin yang kita bedah tuntas di Permission dan Ownership Volume.
Alur keputusan lengkapnya dapat diringkas menjadi diagram berikut.
Diagram di atas dibaca dari atas ke bawah seperti rangkaian pertanyaan. Mari kita telaah tiap cabangnya:
- Pertanyaan pertama menyaring masalahnya — data yang memang sementara, seperti berkas scratch satu sesi, tidak butuh mount apa pun dan cukup menumpang writable layer.
- Cabang kiri menangkap kebutuhan akses host — konfigurasi yang diedit editor dan source code yang diawasi tool development menginginkan berkas yang bisa disentuh langsung dari host; di situlah bind mount unggul.
- Cabang kanan memilah data fana dari data abadi — cache yang boleh dibangun ulang dari nol cocok di tmpfs, sementara data yang harus tetap ada menjawab volume.
Kerangka pemilihan ini akan terus kita pakai sepanjang section, dan chapter penutup section — Memilih Jenis Mount — menguliknya dengan skenario-skenario nyata yang lebih lengkap. Namun teori berhenti di sini: langkah paling meyakinkan adalah melihat data benar-benar selamat dari docker rm dengan mata kepala sendiri. Kita lakukan itu pada Chapter Volume.
Referensi #
- Docker Storage — gambaran resmi tiga jenis mount dan kapan masing-masing dipakai.
- docker run — CLI Reference
— definisi lengkap flag
-v,--mount, dan--tmpfs. - Volumes — volume sebagai pilihan utama untuk data persisten.