Arsip backup/data-web.tar.gz yang kita simpan di penutup Chapter Backup dan Restore Volume kini menunggu sebagai bagasi, dan bagasi memang dibuat untuk berjalan. Backup menjawab bencana; migrasi menjawab rencana — server lama yang mau dipensiunkan, VPS baru yang lebih murah, atau keputusan sederhana seperti mengganti nama volume yang dipakai production. Anehnya, migrasi inilah momen ketika banyak tim kehilangan berkas: image dipindahkan tapi volumenya tidak, data dikopi dengan cp yang kehilangan metadata kepemilikan, atau bind mount lama ditinggalkan karena tidak tahu cara mengubahnya menjadi volume. Chapter ini merangkai tiga strategi pemindahan yang saling melengkapi — arsip yang berjalan kaki lewat scp, salinan langsung antar volume lewat pipa tar, dan konversi bind mount menjadi volume — semuanya memakai bahan yang sudah kita kuasai dari dua chapter sebelumnya.
Skenario: Pindah dari host-a ke host-b #
Skenarionya khas dunia nyata. Situs internal yang dilayani volume data-web selama ini hidup di server lama yang mulai tua — kita sebut saja mesin kita berperan sebagai host-a. Perusahaan menyewa VPS baru dengan hostname host-b.example.com, dan Budi ditugaskan memindahkan situs lengkap dengan imagenya tanpa satu berkas pun tertinggal. Kunci SSH Budi tersimpan sebagai ~/.ssh/kunci-vps, dan akunnya di kedua mesin sudah tergabung dalam grup docker — syarat akses daemon yang kita bahas pada Chapter Mengatur Akses Docker di Section *Instalasi dan Konfigurasi`.
Strategi 1: Berkas Jalan Kaki dengan save dan scp #
Strategi pertama adalah yang paling mudah diaudit: seluruh kepemilikan pindahan diubah menjadi dua berkas biasa, berkas itu dikirim lewat scp, lalu dituangkan kembali di host tujuan. Bagasi volume sudah siap dari chapter sebelumnya, tinggal image yang perlu dibungkus:
$ docker save nginx:1.29-alpine -o nginx-129-alpine.tar
$ ls -lh nginx-129-alpine.tarOutput yang Dihasilkan:
-rw------- 1 budi budi 49M Okt 13 16:24 nginx-129-alpine.tarImage publik seperti nginx sebenarnya bisa ditarik ulang dari Docker Hub di host baru; pola docker save ini justru menunjukkan satu-satunya jalan bagi image privat milik tim yang tidak pernah di-push ke registry mana pun. Kedua berkas berangkat bersama:
$ ssh [email protected] mkdir -p /tmp/migrasi
$ scp backup/data-web.tar.gz nginx-129-alpine.tar [email protected]:/tmp/migrasi/Output yang Dihasilkan:
data-web.tar.gz 100% 612 1.1MB/s 00:00
nginx-129-alpine.tar 100% 49MB 11.2MB/s 00:04Dari titik ini semua perintah dijalankan di host-b. Budi memuat image dan menyiapkan volume kosong:
$ docker load -i /tmp/migrasi/nginx-129-alpine.tarOutput yang Dihasilkan:
Loaded image: nginx:1.29-alpine$ docker volume create data-webOutput yang Dihasilkan:
data-webPemulihan volume dilakukan dengan pola helper restore yang sudah kita latih, kali ini dengan sumber arsip dari /tmp/migrasi:
$ docker run --rm -v data-web:/data -v /tmp/migrasi:/backup:ro alpine:3.20 tar xzf /backup/data-web.tar.gz -C /dataOutput yang Dihasilkan:
Unable to find image 'alpine:3.20' locally
3.20: Pulling from library/alpine
...
Digest: sha256:2676beef0bef...
Status: Downloaded newer image for alpine:3.20Helper image-nya sendiri belum ada di host baru, jadi Docker menariknya lebih dulu — image publik memang selalu tinggal satu docker run saja. Akhirnya situs dinyalakan di host baru dan diuji:
$ docker run -d --name web -p 8080:80 -v data-web:/usr/share/nginx/html nginx:1.29-alpineOutput yang Dihasilkan:
8a4cf4e9028debec8b3e3b1588fef38c9e9a57a0aa4c442bdd56932a4709900d$ curl localhost:8080/halo.txtOutput yang Dihasilkan:
haloMari kita telaah perjalanan Strategi 1 sebagai satu rangkaian:
docker save ... -o berkas.tar— image dibongkar menjadi berkas tar berisi seluruh layer; berkas ini bisa disimpan, diverifikasi checksum-nya, dan dipindahkan seperti berkas besar biasa.scpmengangkut dua berkas sekaligus — arsip volume 612 byte dan image 49MB berbagi satu koneksi; kecepatan transfer 11.2MB/s pada output adalah ilustratif untuk VPS dengan uplink memadai.docker loadmembangunkan image — output satu barisLoaded image: nginx:1.29-alpinemenandakan seluruh layer sudah kembali berdiri di penyimpanan image host-b.- Pemulihan memakai pola yang sama — helper alpine memasang volume tujuan read-write dan arsip read-only; tidak ada satu pun mekanisme baru yang perlu dipelajari, inilah untungnya disiplin pola dari Chapter Backup dan Restore Volume.
curlmenutup migrasi —halo.txtmenjawab dari host baru berarti image, volume, dan konfigurasi mount semuanya sampai utuh.
Strategi 2: Salinan Langsung Antar Volume #
Strategi 1 menghasilkan berkas perantara di disk. Untuk pekerjaan yang sering diulang, perantara itu bisa dihilangkan sama sekali: tar sanggup menulis arsip ke stdout, dan stdout bisa dialirkan lewat pipa langsung ke tar pembaca di sisi lain.
Pipa tar di Host yang Sama #
Kembali ke host-a, kita siapkan volume sumber dari arsip yang masih tersedia, lalu menyalin isinya ke volume baru tanpa satu berkas perantara pun:
$ docker volume create data-lama
$ docker run --rm -v data-lama:/data -v "$(pwd)/backup:/backup:ro" alpine:3.20 tar xzf /backup/data-web.tar.gz -C /data
$ docker volume create data-baru
$ docker run --rm \
-v data-lama:/src:ro \
-v data-baru:/dst \
alpine:3.20 \
sh -c "cd /src && tar cf - . | (cd /dst && tar xf -)"Perintah penyalinan selesai dalam sekejap tanpa output. Verifikasinya kita lakukan dengan dua mata — daftar berkas dengan pemilik numerik, lalu isi berkasnya:
$ docker run --rm -v data-baru:/data alpine:3.20 ls -ln /dataOutput yang Dihasilkan:
total 16
-rw-r--r-- 1 0 0 384 Oct 13 16:33 50x.html
-rw-r--r-- 1 0 0 5 Oct 13 16:33 halo.txt
-rw-r--r-- 1 0 0 615 Oct 13 16:33 index.html
-rw-r--r-- 1 0 0 29 Oct 13 16:33 nota.txt$ docker run --rm -v data-baru:/data alpine:3.20 cat /data/halo.txtOutput yang Dihasilkan:
haloMari kita telaah mesin di balik satu baris pipa itu:
cd /src && tar cf - .—tar cf -menulis arsip ke stdout alih-alih ke berkas; tanda-adalah konvensi “stream”, dan.setelah pindah direktori memastikan isi yang diarsipkan relative dan utuh.| (cd /dst && tar xf -)— tanda kurung melahirkan subshell sehinggacd /dsttidak mengubah direktori kerja shell luar;tar xf -membaca arsip dari stdin dan mengekstraknya tepat di/dst.-v data-lama:/src:ro— sumber dikunci read-only, kebiasaan lama kita; volume tujuan/dstsengaja dibiarkan read-write karena di situlah arsip akan dituang.- Kolom
0 0padals -ln— pemilik dan grup numerik seluruh berkas adalah0 0;tarmemang mempertahankan kepemilikan asli saat menyalin, dan angka-angka inilah yang akan menjadi pokok cerita Chapter Permission dan Ownership Volume.
Pipa tar Lintas Host via ssh #
Pipa yang sama bisa diperpanjang melewati batas host: ssh mengeksekusi docker di host jauh, dan stream arsip mengalir terenkripsi melalui koneksi itu. Sebagai contoh, Budi menarik salinan data-web yang kini hidup di host-b kembali ke laptop sebagai volume bernama data-web-jauh:
$ docker volume create data-web-jauh
$ ssh -i ~/.ssh/kunci-vps [email protected] \
"docker run --rm -i -v data-web:/src:ro alpine:3.20 tar cf - -C /src ." \
| docker run --rm -i -v data-web-jauh:/dst alpine:3.20 tar xf - -C /dstPerintah ini perlu dibedah dengan hati-hati karena banyak yang terjadi dalam satu baris:
- Tanda kutip pada perintah jauh —
docker run ... tar cf - ...berada di dalam kutip ganda sehingga dieksekusi utuh oleh shell host-b; tanpa kutip, kata-katanya akan diurai oleh shell lokal lebih dulu dan hasilnya kacau. -idi kedua sisi — flag interaktif membuat stdin container tetap terbuka; tanpa-i, container pembaca langsung melihat EOF di stdin dan mengekstrak arsip kosong tanpa satu keluhan pun — kegagalan paling sunyi dalam dunia migrasi.tar cf - -C /src .— arsip dibangun di host-b dari volumedata-web, ditulis ke stdout, lalu diangkutsshsebagai aliran byte terenkripsi ke laptop.tar xf - -C /dstdi ujung pipa — helper lokal menerima stream dari stdin dan menuangkannya ke volumedata-web-jauh; arah sebaliknya tinggal menukar posisisshdan helper lokal.- Verifikasi tetap wajib — koneksi yang putus di tengah stream meninggalkan data setengah salinan tanpa pesan galat yang mencolok; ritual
ls -lnpluscatdari subbab sebelumnya adalah satu-satunya penutup yang bisa dipercaya.
Strategi 3: Konversi Bind Mount ke Volume #
Strategi ketiga menjawab keputusan arsitektur: direktori /home/budi/situs — arena latihan bind mount sejak Chapter Bind Mount yang terakhir disunting pada Chapter Memilih Jenis Mount — ingin diubah menjadi volume agar hidup di wilayah kelolaan Docker. Pola pipa yang sama bekerja — hanya sumbernya berganti bind mount:
$ docker volume create situs-statis
$ docker run --rm \
-v /home/budi/situs:/src:ro \
-v situs-statis:/dst \
alpine:3.20 \
sh -c "cd /src && tar cf - . | (cd /dst && tar xf -)"$ docker run --rm -v situs-statis:/data alpine:3.20 cat /data/index.htmlOutput yang Dihasilkan:
<h1>versi 3</h1>Mari kita telaah konversi ini:
- Sumber kini bind mount —
-v /home/budi/situs:/src:romenjembatani direktori host ke helper; direktori host memang bisa dibacatarhost secara langsung, tetapi melewatinya lewat container menjaga satu pola salin yang sama untuk semua jenis sumber. - Seluruh isi direktori ikut pindah —
index.htmlversi 3 hasil suntingan Chapter Memilih Jenis Mount dancatatan.txtbekas latihan Chapter Bind Mount sama-sama mendarat di volume; pipa menyalin keadaan terakhir, bukan keadaan saat direktori pertama dibuat. - Data kini mandiri dari path host — volume
situs-statisbisa dipasang ke container mana pun tanpa peduli di direktori mana ia dijalankan; portabilitas yang dulu menjadi kelemahan bind mount kini diperoleh penuh.
Tabel Strategi Migrasi #
| Strategi | Jalur data | Perlu berkas image? | Cocok untuk |
|---|---|---|---|
| 1. save + arsip + scp + load | host-a → berkas → host-b | Ya — docker save dan docker load | Migrasi total sekali jalan ke host baru yang kosong |
| 2a. Pipa tar antar volume | volume → volume di host yang sama | Tidak | Duplikasi volume, penggantian nama, penyiapan volume uji |
| 2b. Pipa tar lintas host | volume di host jauh → volume lokal | Tidak | Sinkronisasi rutin tanpa berkas perantara |
| 3. Bind mount → volume | direktori host → volume | Tidak | Membawa data masuk ke kelolaan Docker |
Sebelum menutup, kita rapikan volume perantara yang sudah menuntaskan tugasnya; data-baru dan situs-statis dibiarkan sebagai hasil akhir latihan:
$ docker volume rm data-lama data-web-jauhOutput yang Dihasilkan:
data-lama
data-web-jauhTiga strategi di atas berhasil memindahkan byte demi byte — tetapi perhatikan bahwa seluruh verifikasi kita menatap satu kolom yang sama berulang-ulang: angka 0 0 di ls -ln. Angka itu tampak polos, padahal inilah biang dari separuh tiket “container saya tidak bisa menulis” di forum: kernel Linux tidak mengenal nama user root atau app, ia hanya mencocokkan UID dan GID numerik — dan angka yang sama bisa berarti user berbeda di image yang berbeda. Chapter Permission dan Ownership Volume membedah mesin pencocokan angka itu dari dua arah, lalu melengkapi kotak obat kita dengan lima pola solusi untuk konflik kepemilikan yang paling sering terjadi.
Referensi #
- Volumes — bagian resmi backup, restore, dan migrasi antar volume.
- docker image save — referensi pembungkusan image menjadi berkas tar.
- docker image load — referensi pemuatan kembali image dari berkas tar.