Apa cara yang benar untuk menambahkan data ke volume bernama yang ada di Docker?

91

Saya menggunakan Docker dengan cara lama, dengan wadah volume:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

Tapi sekarang saya berubah ke cara baru dengan membuat volume bernama:

 docker volume create --name my-jenkins-volume 

Saya mengikat volume baru ini ke wadah Jenkins baru. Satu-satunya hal yang saya tinggalkan adalah folder di mana saya memiliki /var/jenkins_homewadah jenkins saya sebelumnya. (dengan menggunakan docker cp) Sekarang saya ingin mengisi volume baru saya dengan konten folder itu.

Bisakah saya menyalin konten folder itu ke /var/lib/jenkins/volume/my-jenkins-volume/_data?

DenCowboy
sumber

Jawaban:

141

Anda pasti dapat menyalin data secara langsung /var/lib/docker/volumes/my-jenkins-volume/_data, tetapi dengan melakukan ini Anda:

  • Mengandalkan akses fisik ke host buruh pelabuhan. Teknik ini tidak akan berfungsi jika Anda berinteraksi dengan api buruh pelabuhan jarak jauh.

  • Mengandalkan aspek tertentu dari implementasi volume akan dapat berubah di masa depan, merusak proses apa pun yang Anda miliki yang bergantung padanya.

Saya pikir Anda lebih baik mengandalkan hal-hal yang dapat Anda capai menggunakan api buruh pelabuhan, melalui klien baris perintah. Solusi termudah mungkin hanya dengan menggunakan penampung pembantu, seperti:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper
larsks
sumber
3
Mengenai poin kedua Anda, Anda dapat berlari docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'untuk mendapatkan lokasi fisiknya secara terprogram. Masih belum terasa seperti ide yang bagus.
c24w
9
Penampung pembantu ini tidak perlu benar-benar dijalankan. Cukup dengan membuatnya, lalu jalankan docker cpdan hapus.
Alex
Anda tidak bisa mengeksekusi ke dalam wadah itu untuk melihat hasil atau mengubah file secara manual.
CodeOrElse
3
Perhatikan bahwa daftar /var/lib/docker/volumes/my-jenkins-volume/_datasaat menggunakan Docker untuk Mac tidak berfungsi karena file disimpan di dalam mesin virtual xhyve . Lihat forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni
1
Benar dijelaskan di sini stackoverflow.com/questions/29762231/…
Zuabi
32

Anda dapat mengurangi jawaban yang diterima menjadi satu baris menggunakan, misalnya

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data
headdab
sumber
1
im bertanya-tanya apakah sifat sementara / tmp dapat menimbulkan risiko penampung mungkin menghapus data Anda sebelum cp selesai? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
tiba
1
Tautan tidak benar-benar menjelaskan masa pakai file di / tmp. Saya menyatakan: "Program tidak boleh berasumsi bahwa file atau direktori apa pun di / tmp disimpan di antara pemanggilan program." yang menyiratkan bahwa file tersebut akan bertahan, tapi itu jaminan. Opsi -v untuk buruh pelabuhan akan membuat direktori dalam wadah jika tidak ada, jadi mengubah / tmp / src ke / src akan berfungsi jika Anda khawatir tentang kondisi balapan potensial ini. Saya akan mengedit jawaban untuk mencerminkan ini, karena tidak ada kerugian.
headdab
3
tidak -v `pwd`:/srcmenyiratkan bahwa perintah berjalan di host? (Bagaimana bisa host memetakan pwdjika itu mesin yang berbeda, misalnya? - tidak bisa.) Jika perintah buruh pelabuhan tidak berjalan pada host ini tidak berfungsi. Saya percaya itu sebabnya kami memiliki docker cp. Sepertinya ini bukan "cara" untuk buruh pelabuhan - ini hanya kasus khusus yang hanya bekerja ketika perintah buruh pelabuhan berjalan di host. Apakah saya mengerti dengan benar?
Wyck
Ya, saya pikir Anda benar. pwdharus menyelesaikan file di mesin host. Dari dokumentasi pemasangan buruh pelabuhan: "Dalam kasus pemasangan bind, bidang pertama adalah jalur ke file atau direktori pada mesin host."
headdab
1
Oleh karena itu, ini tidak berfungsi untuk menyalin file lokal Anda ke dalam wadah jika di host jarak jauh, karena Anda memasang pwdyang bahkan tidak perlu ada di host jarak jauh. Sebagai gantinya solusi oleh Dmytro Melnychuk (buat + cp + rm) tidak menyalin yang lokal ke dalam wadah di mana pun ia berjalan.
Xavi Montero
27

Anda tidak perlu memulai beberapa penampung untuk menambahkan data ke volume bernama yang sudah ada, cukup buat penampung dan salin data di sana:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp
Dmytro Melnychuk
sumber
2
Asalkan konten busybox tidak terlalu dibutuhkan; Anda dapat melakukan ini dengan hello-worlddan itu juga berhasil. busyboxberukuran 1,22MB. Sebaliknya hello-worldadalah 13.3kB. Pertanyaannya adalah: Dengan cara yang sama kita dapat melakukan Dockerfile DARI awal, dapatkah kita melakukan "pembuatan kontainer buruh pelabuhan" dengan "tidak ada" sebagai gambar karena kita hanya ingin "memasang" volume dan tidak pernah memulai wadah?
Xavi Montero
1
+1 untuk solusi ini di atas yang dipilih tetapi sintaks yang benar docker cpadalahdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal
4

Berikut langkah-langkah untuk menyalin konten ~ / data ke volume buruh pelabuhan bernama my-vol

Langkah 1. Pasang volume ke wadah "sementara". Untuk itu jalankan di terminal perintah ini:

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

Langkah 2. Salin konten ~ / data ke my-vol . Untuk itu jalankan perintah ini di jendela terminal baru:

cd ~/data docker cp . alpine:/data

Ini akan menyalin konten ~ / data ke volume-saya . Setelah menyalin keluar dari wadah sementara.

Namik Hajiyev
sumber