Bagaimana saya bisa menambahkan volume ke wadah Docker yang ada?

297

Saya memiliki wadah Docker yang saya buat hanya dengan menginstal Docker di Ubuntu dan melakukan:

sudo docker run -i -t ubuntu /bin/bash

Saya segera mulai menginstal Java dan beberapa alat lainnya, menghabiskan waktu dengannya dan menghentikan wadah

exit

Kemudian saya ingin menambahkan volume dan menyadari bahwa ini tidak semudah yang saya kira. Jika saya gunakan sudo docker -v /somedir run ...maka saya akan berakhir dengan wadah baru yang baru, jadi saya harus menginstal Java dan melakukan apa yang telah saya lakukan sebelumnya hanya untuk sampai pada sebuah wadah dengan volume terpasang.

Semua dokumentasi tentang pemasangan folder dari host tampaknya menyiratkan bahwa pemasangan volume adalah sesuatu yang dapat dilakukan saat membuat wadah. Jadi satu-satunya pilihan saya harus menghindari mengkonfigurasi ulang wadah baru dari awal adalah untuk mengkomit wadah yang sudah ada ke repositori dan menggunakannya sebagai dasar yang baru saat memasang volume.

Apakah ini satu-satunya cara untuk menambahkan volume ke wadah yang ada?

mahonya
sumber
1
Setelah Kontainer, ini menjadi bagian integral dari Programmer dan karenanya pertanyaan seperti itu lebih sering diposting di sini. Pertanyaan yang diposting di sini menggunakan dockertag adalah 34k + , yang jauh lebih dari dua situs tersebut stackoverflow.com/questions/tagged/docker
MA Hossain Tonu

Jawaban:

394

Anda dapat mengkomit wadah Anda yang sudah ada (yaitu membuat gambar baru dari perubahan wadah) dan kemudian menjalankannya dengan mount baru Anda.

Contoh:

$ docker ps  -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                          PORTS               NAMES
    5a8f89adeead        ubuntu:14.04          "/bin/bash"              About a minute ago   Exited (0) About a minute ago                       agitated_newton

$ docker commit 5a8f89adeead newimagename

$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

Jika semuanya baik-baik saja, hentikan wadah lama Anda, dan gunakan yang baru ini.

Itu dia :)

Leonardo Cuquejo
sumber
22
Dan jika Anda membutuhkan wadah baru untuk mengambil nama lama karena alasan tertentu, gunakan nama buruh pelabuhan setelah menghapus yang lama.
Dirk
10
hanya ingin menunjukkan bahwa di atas di mana Anda menyebutkan newnameofcontainerbahwa ini mungkin harus dinamai new_image_name- karena docker commitmembuat gambar baru di sistem Anda. Kemudian di berikut ini ketika Anda melakukan docker runAnda benar-benar menggunakan nama gambar yang Anda ingin menjalankan wadah baru. Di atas berfungsi tetapi hanya ingin menjelaskan kepada orang lain bahwa placeholder newnameofcontainer di atas sebenarnya adalah nama untuk gambar baru. Terima kasih! jawaban yang luar biasa. oh, Anda dapat melihat gambar yang baru dibuat dari perintah commit buruh pelabuhan pertama menggunakandocker image ls
FireDragon
3
Bahkan, Anda tidak perlu membuat wadah baru jika Anda ingin memulai dari gambar. Baik docker run -v /srv/a:/tmp ubuntu:14.04itu baik.
YongHao Hu
Saya sudah memiliki wadah yang berjalan dengan semua file. jika metode di atas membuat wadah baru, saya tidak dapat membangun semuanya dari sekali lagi. Apakah ada cara saya dapat menghindari ini dan memasang tanpa harus membuat wadah atau gambar baru?
dhinar
Apakah ini akan menjaga pemetaan volume lama dari wadah lama atau haruskah saya mendeklarasikan ulang dengan wadah baru juga?
thebeancounter
79

Kami tidak memiliki cara untuk menambahkan volume dalam menjalankan wadah, tetapi untuk mencapai tujuan ini Anda dapat menggunakan perintah di bawah ini:

Salin file / folder antara wadah dan sistem file lokal: -

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

Untuk referensi lihat:

https://docs.docker.com/engine/reference/commandline/cp/

pengguna128364
sumber
47
Ada perbedaan besar antara memasang volume dan menyalin file ke dan dari sebuah wadah ...
Jules
31
Pokoknya itu membantu saya. Saya tidak tahu perintah 'buruh pelabuhan cp', dan berusaha untuk mencapai ini - salin file dari menjalankan kontainer ke host.
Ivan
3
ini bukan mount, tetapi berguna untuk mengembalikan file dan buih antara container dan host lokal.
linehrr
Meskipun hal ini memecahkan masalah mereplikasi konten kontainer secara lokal, ini tidak mendekati setara dengan pemasangan volume dan tidak boleh dianggap sebagai alternatif. Yaitu, replikasi harus dikelola oleh pengguna, dan data ada sekarang di dua tempat.
Sebastian Gaweda
1
Saya tidak mengerti mengapa begitu banyak suara, ini adalah jawaban yang sangat salah untuk pertanyaan yang diajukan.
João Matos
33

Saya telah berhasil memasang /home/<user-name>folder host saya ke /mntfolder wadah yang ada (tidak berjalan). Anda dapat melakukannya dengan cara berikut:

  1. Buka file konfigurasi yang terkait dengan wadah yang dihentikan, yang dapat ditemukan di /var/lib/docker/containers/99d...1fb/config.v2.json(mungkin config.jsonuntuk versi buruh pelabuhan yang lebih tua).

  2. Cari MountPointsbagian yang kosong dalam kasus saya: "MountPoints":{}. Selanjutnya ganti konten dengan sesuatu seperti ini (Anda dapat menyalin konten yang tepat dari wadah lain dengan pengaturan yang tepat):

"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}

atau sama (diformat):

  "MountPoints": {
    "/mnt": {
      "Source": "/home/<user-name>",
      "Destination": "/mnt",
      "RW": true,
      "Name": "",
      "Driver": "",
      "Type": "bind",
      "Propagation": "rprivate",
      "Spec": {
        "Type": "bind",
        "Source": "/home/<user-name>",
        "Target": "/mnt"
      },
      "SkipMountpointCreation": false
    }
  }
  1. Mulai ulang layanan buruh pelabuhan: service docker restart

Ini berfungsi untuk saya dengan Ubuntu 18.04.1 dan Docker 18.09.0

Igor Bendrup
sumber
3
Terima kasih atas jawabannya. Langkah 3 sangat penting. Saya juga akan menambahkan bahwa lebih baik untuk menghentikan wadah buruh pelabuhan terlebih dahulu sebelum melakukan penulisan.
buzypi
7
Ini adalah jawaban terbaik karena benar-benar menjaga wadah yang ada. Inilah yang saya lakukan: 1. Hentikan mesin buruh pelabuhan: systemctl stop docker.service2. Edit config.v2.json: vim <(jq . /var/lib/docker/containers/<container-ID>/config.v2.json)3. Simpan pembaruan ke file: :w config.v2.json4. Keluar vim: :q!5. Perbarui file yang ada: jq -c . config.v2.json > /var/lib/docker/containers/<container-ID>/config.v2.json6. Mulai mesin buruh pelabuhan: systemctl start docker.service7. Mulai wadah jika perlu : docker start <container-name/ID>8. Nikmati :-)
Kontrol Android
2
Langkah kuncinya adalah service docker restart. Saya mencoba untuk docker restart <container>kemudian konfigurasi baru tidak diambil, dan itu ditimpa oleh konfigurasi lama.
KFL
1
Juga jqakan membantu cukup mencetak JSON sehingga lebih dapat diedit:cat config.v2.json | jq . > config.json
KFL
14

Jérôme Petazzoni memiliki posting blog yang cukup menarik tentang cara Melampirkan volume ke wadah saat sedang berjalan . Ini bukan sesuatu yang dibangun di Docker di luar kotak, tetapi mungkin untuk dicapai.

Saat ia juga menunjukkan

Ini tidak akan berfungsi pada sistem file yang tidak didasarkan pada perangkat blok.

Ini hanya akan berfungsi jika / proc / mounts mencantumkan dengan benar node device block (yang, seperti yang kita lihat di atas, belum tentu benar).

Juga, saya hanya menguji ini di lingkungan lokal saya; Saya bahkan tidak mencoba contoh cloud atau semacamnya

YMMV

R0MANARMI
sumber
8

Sayangnya opsi sakelar untuk memasang volume hanya ditemukan dalam runperintah.

docker run --help

-v, --volume list Bind mount a volume (default [])

Ada cara Anda dapat mengatasi ini sehingga Anda tidak perlu menginstal ulang aplikasi yang sudah Anda siapkan di wadah Anda.

  1. Ekspor kontainer Anda docker container export -o ./myimage.docker mycontainer
  2. Impor sebagai gambar docker import ./myimage.docker myimage
  3. Kemudian docker run -i -t -v /somedir --name mycontainer myimage /bin/bash
Adel Helal
sumber
1
FYI - docker containerbukan perintah yang valid pada 1.11.2 (yang merupakan versi terbaru yang didukung oleh Synology pada tulisan ini). Saya tidak dapat menemukan dokumen yang mengatakan kapan ditambahkan. Dalam hal ini perintah pertama adalah docker export -o ./myimage.docker mycontainer.
Chris R. Donnelly
2

Catatan untuk menggunakan wadah Docker Windows setelah saya harus mencari masalah ini untuk waktu yang lama!

Kondisi:

  • Windows 10
  • Docker Desktop (versi terbaru)
  • menggunakan Docker Windows Container untuk image microsoft / mssql-server-windows-developer

Masalah:

  • Saya ingin memasang kamus host ke wadah windows saya.

Solusi seperti yang sebagian dijelaskan di sini:

  • buat wadah buruh pelabuhan

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer

  • pergi ke shell perintah dalam wadah

docker exec -it <CONTAINERID> cmd.exe

  • buat DIR

mkdir DirForMount

  • hentikan wadah

docker container stop <CONTAINERID>

  • wadah komitmen

docker commit <CONTAINERID> <NEWIMAGENAME>

  • hapus wadah lama

docker container rm <CONTAINERID>

  • buat wadah baru dengan pemasangan gambar dan volume baru

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>

Setelah ini saya memecahkan masalah ini pada kontainer windows buruh pelabuhan.

droebi
sumber
-3

Cara terbaik adalah menyalin semua file dan folder di dalam direktori di sistem file lokal Anda dengan: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

SRC_PATHada di wadah DEST_PATHada di localhost

Kemudian lakukan docker-compose downpasang volume ke yang sama DEST_PATHdan jalankan wadah Docker dengan menggunakandocker-compose up -d

Tambahkan volume dengan mengikuti docker-compose.yml

volumes:
 - DEST_PATH:SRC_PATH
Vatsal Mishra
sumber
Ada pilihan lain yang lebih baik di atas.
MrR
Memang, ada opsi yang lebih baik di atas, dan menyalin file di sekitar tidak me-mount mereka. Selain itu, definisi "volume" yang diberikan untuk opsi penulisan komposisi buruh pelabuhan adalah sebaliknya: volume: - HOST_PATH: CONTAINER_PATH
Guillaume S.