Dosyaları ana bilgisayardan Docker kapsayıcısına kopyalama


1578

Çalıştığımız Docker kapsayıcıları için bir yedekleme ve geri yükleme çözümü oluşturmaya çalışıyorum.

Oluşturduğum Docker temel görüntüsüne sahibim ubuntu:baseve her seferinde dosya eklemek için bir Docker dosyasıyla yeniden oluşturmak istemiyorum.

Ana makineden çalışan ve ubuntu:baseDocker görüntüsünü kullanarak yeni bir kapsayıcı oluşturur ve sonra dosyaları bu kapsayıcıya kopyalayan bir komut dosyası oluşturmak istiyorum .

Ana bilgisayardan konteynere nasıl dosya kopyalayabilirim?


11
Yeniden inşa etmek istemiyorsanız, neden " liman işçiliği taahhüt " olmaz? Bu, görüntünüzü kaydeder.
Berend de Boer

27
Sadece kimsenin değinmediği bir kavram üzerine bir açıklama: genel olarak, kaplara "geçici" muamele edin. Çalışan bir kapsayıcıya / test dosyaları (test, prototipleme) kopyalamak için durumlar vardır. Ancak kendinizi Dockerfiles kullanarak ve / veya beste kullanarak ihtiyacınız olanı yeniden inşa edemeyeceğiniz bir konumda bulursanız, kötü bir yerde olabilirsiniz. Genellikle kapsayıcıları OS veya VM nesneleriymiş gibi yedeklemek istemezsiniz. Genel olarak konuşursak :-)
Scott Prive

Yanıtlar:


2674

cpKomut dosyalarını kopyalamak için kullanılabilir.

Belirli bir dosya aşağıdaki gibi kaba kopyalanabilir:

docker cp foo.txt mycontainer:/foo.txt

Belirli bir dosya konteynırdan aşağıdaki gibi kopyalanabilir:

docker cp mycontainer:/foo.txt foo.txt

Vurgu için, mycontainera, kap İD, olmayan bir görüntü İD.

Klasörün içerdiği birden fazla dosya, aşağıdakiler kullanılarak klasöre srckopyalanabilir target:

docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target

Başvuru: Docker CLI dokümanlarıcp

1.8'den önceki Docker sürümlerinde, dosyaları yalnızca bir kaptan ana bilgisayara kopyalamak mümkün oldu. Ana bilgisayardan bir kaba değil.


2
Ayrıca bu konak vm veya ana OS üzerinde olabilir dikkat ve konak (veya ana os) için konteyner veya vm ya ev sahibi çalışır
Adam Tuliper - MSFT

7
Bir Dockerfile dosyasında, derleme sırasında dosya eklemek için ADD anahtar sözcüğünü kullanabilirsiniz.
0x7d7b

4
@ h3nrik uygulanabilir olduğunda COPYtercih edilirADD .
Franklin Yu

10
docker cpana bilgisayardan konteynere kopyalamak için kullanın iyi çalışır, ancak ana bilgisayardan konteynere dosya kopyalamak için kullanıldığında, hiçbir etkisi ... kimse neden biliyor? docker sürümü: Docker sürüm 1.10.3, cb079f6 desteksiz derleme
Ace.Yin

2
Docker cp'yi kullanarak ana bilgisayardan konteynere birden fazla dosya kopyalayabilir miyim?
Yogesh

182
  1. Kapsayıcı adını veya kısa kapsayıcı kimliğini alın:

    $ docker ps
    
  2. Kapsayıcı kimliğinin tamamını alın:

    $ docker inspect -f   '{{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
    
  3. Dosya kopyalamak:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
    

MİSAL:

$ docker ps

CONTAINER ID      IMAGE    COMMAND       CREATED      STATUS       PORTS        NAMES

d8e703d7e303   solidleon/ssh:latest      /usr/sbin/sshd -D                      cranky_pare

$ docker inspect -f   '{{.Id}}' cranky_pare

veya

$ docker inspect -f   '{{.Id}}' d8e703d7e303

d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5

$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt

13
Benim için ana bilgisayarın montaj yolu içermiyordu aufsama bir devicemapper. Kapların montaj yolunu (çalışırken) kontrol etmenin en kolay yolu komutu çalıştırmaktır mount.
derenio

3
Yukarıdaki çözümü denedim. Dosyaları docker'a özgü dizine kopyaladı. Ancak, docker konteyner için bash kullandığımda, dosyalar orada görünmüyor. Kaçırdığım bir şey var mı?
AppleBud

2
Yeni yol / var / lib / docker / devicemapper / mnt / <<id>> /
rootfs

4
Benim için Docker /var/lib/docker/aufs/diff/<id>/
1.4.1'de

3
Kötü MacOS kullanıcıları için ne dersiniz? Bağlama dizini /var/libbenim için. find / -name dockerya da yardımcı olmadı.
prayagupd

141

En temiz yol, kapsayıcıyı başlatırken kapsayıcıya bir ana bilgisayar dizini eklemektir:

{host} docker run -v /path/to/hostdir:/mnt --name my_container my_image
{host} docker exec -it my_container bash
{container} cp /mnt/sourcefile /path/to/destfile

3
nasıl konteyner çalıştırabilirsiniz? Bunu sadece bir görüntü ile yapabileceğini düşündüm.
Pavel Zaitsev

Konteyner var olduğunda aka daha önce çalıştırmak çalışamıyorum. Aşağıdaki Tar güzel çalışıyor.
Eino Mäkitalo

1
Bunun benim için işe yaradığı tek yol, görüntüyü çalıştırmanın yanı sıra (kabı somutlaştırmak) hacmini bağlamaktı. Şununla sona erdi:docker run -d -p -v /host/path:/mnt --name container_name image_name
peter n

2
Bu benim için işe yaramıyor. En az bir konteyner çalıştıramaz. Sadece resim çalıştırabilir
Shashank Hegde

1
Bunun docker cptek yönlü bir operasyon olduğuna şaşırdım !
ThorSummoner

115

Aşağıdaki oldukça çirkin bir yoludur ama işe yarıyor.

docker run -i ubuntu /bin/bash -c 'cat > file' < file

7
Harika çalışıyor! Ama değişim işlemeye unutma: docker commit `docker ps -l -q` ubuntu-with-file. Yoksa değişiklik kaybolacak (bunun yerine istediğiniz adı kullanın ubuntu-with-file)
Michael_Scharf

@Erik: Konteyner çalışırken dosya nerede bulunur?
coanor

49
Ayrıca, docker execçalışan konteyner ile çalışmak için yeni bir özellik kullanabiliriz :docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
Mikl

17
@Mikl Bunun docker exec -i ...yerine olması gerektiğini düşünüyorum -it, çünkü bir dosyadan içeri aktarırken TTY yok.
z0r

4
Hala tar -c -v -f - /path/to/host/directory | docker exec -i <container-name> bash -c 'tar -x -v --strip-components 1 -f - -C /path/to/container/directory'
Docker'ın

43

Bunu çalışan bir kapsayıcıda yapmanız gerekiyorsa docker exec (1.3'e eklenir) kullanabilirsiniz.

İlk olarak, kabın adını veya kimliğini bulun:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMES
b9b7400ddd8f        ubuntu:latest                "/bin/bash"         2 seconds ago       Up 2 seconds                                elated_hodgkin

Örnekte birini kullanabilirsiniz üzerinde b9b7400ddd8fya da elated_hodgkin.

Her şeyi kopyalamak istiyorsanız /tmp/somefilesAna bilgisayardaki/var/www konteynere :

$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www

Daha sonra /bin/bashkapta yürütülebilir ve çalıştığını doğrulayabiliriz:

$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1  file2

Centos 7.4'te docker 1.16 üzerinde harika çalışıyor Harika yenilikçi fikir.
Dudi Boy

41
  1. Yeni bir dockerfile dosyası oluşturun ve mevcut görüntüyü temel olarak kullanın.

    FROM myName/myImage:latest
    
    ADD myFile.py bin/myFile.py
    
  2. Ardından kabı oluşturun:

    docker build .
    

2
Bu benim için işe yaradı. Başka hiçbir şey. Teşekkür ederim!
Owen

Doğrudan yeni bir kap değil, yeni bir görüntü oluşturur. MyFile.py değiştiğinde bu görüntüyü yeniden kullanırsanız, görüntüyü yeniden oluşturmazsanız dosyanın eski sürümünü kullanır.
Guillaume Lebreton

Bunu en uzak yolu yalnızca uzak bir sunucuda test ediyorsanız buluyorum.
Dominik Krulak

Göre bu çoğu insan yerine ADD daha KOPYA kullanmalıdır. Ancak yerel dosyalar için (bu örnekte olduğu gibi) eşdeğerdir.
hoosierEE

39

Çözüm aşağıda verilmiştir,

Docker kabuğundan,

root@123abc:/root#  <-- get the container ID

Ana bilgisayardan

cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root

Dosya, kabın dosya sisteminde bulunduğu konuma doğrudan kopyalanacaktır.


10
Mükemmel cevap. Daha yeni docker sürümlerinde yol, / var / lib / docker / aufs / mnt / olarak yeniden adlandırıldı
Alex Volkov

cihaz haritası yolu liman işçisi 1.6 ile fedora üzerinde çalışmıyor gibi görünüyor. Ayrı bir Q olarak koydunuz, stackoverflow.com/questions/29939419/… , herhangi bir yorum takdir edilecektir.
Yogesh_D

33

Genellikle üç tür vardır:

  1. Bir konteynırdan ana bilgisayara

    docker cp container_id:./bar/foo.txt .
    

dev1

  1. Ana bilgisayardan bir konteynere

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev2

  1. Bir kaptan bir kaba 1 ve 2 karışımları

    docker cp container_id1:./bar/foo.txt .
    
    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev3


6
docker cp her iki yönde de çalışır. Yürütmeye, kedi kurmaya ve yönlendirmeye gerek yok. docker cp host_file.txt konteyner: / yol /
tbm

32

Çalışan bir kapsayıcıya dosya kopyalamak için başka bir çözüm tar kullanıyor:

tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x

Dosyayı kabın foo.shiçine kopyalar /tmp.

Düzenleme: Maarten s yorum -fsayesinde reduntant kaldırın .


Bir dizinin tamamını göndermeniz gerekiyorsa bu iyidir. Tek bir dosya için Erik'in cevabı daha basittir.
Kelvin

1
@Kelvin: Ancak katran da dosya özniteliklerini ve adını korur. Diğerlerinin yanı sıra, adı yalnızca bir kez yazmanız gerektiği anlamına gelir (ve orada kabuğunuzdan sekme tamamlama elde edersiniz). Bu yüzden katranın konteynerde yüklü olduğu sürece aslında daha basit olduğunu söyleyebilirim.
Maarten

1
Yine -f -de biraz gereksiz, varsayılan davranış yine de stdout yazmaktır.
Maarten

Bu, tar
cellige'e

Haklısınız - sunucuya ve konteynerin içine kurulacak katran gerekir. Günümüzde docker cp kullanmak daha iyi bir çözümdür.
joemat

24

Dosyayı ana bilgisayardan çalışan kapsayıcıya kopyalamak için

docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH

Dayanarak Erik'in cevap ve Mikl en ve z0r yorumlarından.


Kabul edilen çözümler bazen çalışan kaplara aktarırken dosyaların girintisini bozar. Bu, bu tür durumlar için mükemmel çalışır
Düşler


15

Bu, başlığında bu soruda yer alan 'Ana bilgisayardan Docker kapsayıcısına dosya kopyalama' sorusuna doğrudan bir cevaptır.

Deneyin docker cp. Bunu yapmanın en kolay yolu ve Mac'imde bile çalışıyor. Kullanımı:

docker cp /root/some-file.txt some-docker-container:/root

Bu dosyayı kopyalar some-file.txtdizinde /rootadında Docker konteyner içine ana makinede some-docker-containerdizine /root. Güvenli kopya sözdizimine çok yakın. Ve bir önceki gönderide gösterildiği gibi, tam tersini kullanabilirsiniz. Yani, dosyaları konteynerden ana bilgisayara da kopyalarsınız.

Ve bu yazıyı indirmeden önce lütfen girin docker cp --help. Belgeleri okumak bazen çok yardımcı olabilir ...

Bu şekilde hoşlanmıyorsanız ve zaten oluşturulmuş ve çalışmakta olan kapsayıcısında veri hacimleri istiyorsanız, bugün eğlence tek seçeneğinizdir. Ayrıca bkz. Varolan bir Docker kapsayıcısına nasıl birim ekleyebilirim? .


15

Burada (yükseltilmiş) çözümlerin çoğunu denedim ama docker 17.09'da (2018'de) artık / var / lib / docker / aufs klasörü yok.

Bu basit docker cpbu görevi çözdü.

docker cp c:\path\to\local\file container_name:/path/to/target/dir/

Container_name nasıl edinilir?

 docker ps 

Bir NAMESbölüm var. A kullanmayın IMAGE.


12

Bir kapsayıcı ile yerel dosya sistemi arasında dosya / klasör kopyalamak için şu komutu yazın:

docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}

Örneğin,

docker cp /home/foo container-id:/home/dir

Contianer kimliğini almak için verilen komutu yazın:

docker ps

Yukarıdaki içerik docker.com adresinden alınmıştır .


8

Kapsayıcı zaten çalışıyorsa, verilen komutu yazın:

# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"

Paylaşılan dizini kullanarak dosya paylaşmak için verilen komutu yazarak kapsayıcıyı çalıştırın:

# docker run -v /path/to/host/dir:/path/to/container/dir ...

Not: Kabın kullanıcıları, ana bilgisayarın kullanıcılarıyla aynı olmadığından, izinlerle ilgili sorunlar ortaya çıkabilir.


1
Ayrıca:docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
Mikl

2
catÇıktıktan sonra sonlandırılmayacağını unutmayın . Sizin için önemliyse (bash komut dosyalarını kopyalıyorsanız, bash bunları çalıştırmayı reddeder), söz konusu dosyayı tutan işlemi çalıştırmalı lsof | grep yourfilenameve öldürmelisiniz cat.
johndodo

Teşekkür! Harika bir ipucu. Lütfen bana bu işlemi tek bir komutla nasıl öldüreceğimizi söyleyebilir misiniz? Gibi bir şey kill $(lsof | grep /path/to/file | sed ...). Yardımınız için minnettar olacağım
Mikl

kill $(docker top CONTAINERNAME | sed -n '/cat$/p' | sed 's/^root[^0-9]\+\([0-9]\+\).*$/\1/')
Mikl

8

Bu, Docker'dan Host cihazına veri kopyalama komutudur:

docker cp container_id:file path/filename /hostpath

docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

Aşağıda ana bilgisayardan docker'a veri kopyalama komutu verilmiştir:

docker cp a.txt ccfbeb35116b:/home/

7

Docker ortamında tüm kapsayıcılar dizinde bulunur:

/var/lib/docker/aufs/required-docker-id/

Kaynak dizini / dosyayı kapsayıcının herhangi bir bölümüne kopyalamak için verilen komutu yazın:

sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/


5

tarve docker cpbir dizindeki her şeyi kopyalamak için iyi bir kombinasyon.

Veri hacmi kapsayıcısı oluşturma

docker create --name dvc --volume /path/on/container cirros

Dizin hiyerarşisini korumak için

tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container

İşini kontrol et

docker run --rm --volumes-from dvc cirros ls -al /path/on/container

5

Ana bilgisayar CentOS veya Fedora ise, içinde bir proxy yoktur /var/lib/docker/aufs, ancak altındadır /proc:

cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root

Bu cmd datadizinin tüm içeriğini /"containerid" kimliğine sahip konteynere kopyalayacaktır .


Bu Redhat'a özgü değildir: Debian üzerinde de çalışır. (belki de tüm Gnu / Linux ile /proc). Ayrıca, dosyayı sadece kök değil başka bir yere koymak için yolu uzatın.
ctrl-alt-delor

5

mycontainer@ H3nrik cevabında benim gibi biri için ne anlama geldiği belli değilse , aslında kapsayıcı kimliği. Bir dosyayı kopyalamak için WarpSquare.mp4de /app/example_scenes/1440p60bunu kullandım geçerli klasöre bir çıkıldı liman işçisi kabından.

docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .

burada docker ps -q -lson çıkan örneğin kapsayıcı kimliğini alır. Çıktığı bir kap değilse, docker container lsveyadocker ps


1
Çıkılan kapsayıcıların kimliklerini docker ps -aveya ile listeleyebilirsiniz docker container ls -a.
0x7d7b

4

Bu soruyu bulan birçok kişi, dosyaları oluşturulurken Docker görüntüsüne kopyalama sorunu yaşayabilir. (yaptım).

Bu durumda, görüntüyü oluşturmak için kullandığınız COPYkomutu Dockerfilekullanabilirsiniz.

Belgelere bakın .


4

Yerel makinenizin IP adresini kullanarak

ifconfig

Ardından Docker kabınıza girin ve şunu yazın

scp user_name@ip_address:/path_to_the_file destination

Her durumda yüklü bir SSH istemciniz ve sunucunuz yoksa şunu kullanarak yükleyin:

sudo apt-get install openssh-server

Çok teşekkürler, benim için iyi çalıştı. Artı, diğer yollardan daha verimli buldum
user1314742

Bu, güvenlik açısından korkunç bir çözümdür.

4

Bu, tomcat kapsayıcısını çalıştırırken tek bir dosyayı kopyalamak için kullanılan bir çevrimiçi dosyadır.

docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat

Bu, savaş dosyasını webapps dizinine kopyalar ve uygulamanızın hemen çalışmasını sağlar.


1
-v kopyalanmayacak (yani bir bağlantı oluşturacak)
bağlanacak

Sonuç farkı artık önceki konteyner klasör içeriğini göremiyorum klasör gizler önceki konteyner içeriği, örneğin montaj Eğer bir kap üzerinde bir konak klasörü monte eğer olmasıdır
ÇBİÖ'nün

4

Kapsayıcı Sözdizimi:

 docker run -v /HOST/folder:/Container/floder 

Docker Dosyasında

COPY hom* /myFolder/        # adds all files starting with "hom"
COPY hom?.txt /myFolder/    # ? is replaced with any single character, e.g., "home.txt"

3

Bulduğum kapsayıcıya dosya kopyalamanın en iyi yolu -v, docker run komutu seçeneğini kullanarak ana makineye bir dizin monte etmektir .


3

İyi cevaplar var, ama çok spesifik. docker psİlgilendiğiniz kapsayıcı kimliği almanın iyi bir yol olduğunu öğrendim .

mount | grep <id>

birimin nereye monte edildiğini görmek için. Yani en

/var/lib/docker/devicemapper/mnt/<id>/rootfs/

benim için, ancak işletim sistemine ve yapılandırmaya bağlı olarak farklı bir yol olabilir. Şimdi dosyaları bu yola kopyalayın.

Kullanımı -vher zaman pratik değildir.


3

VLC'yi derlemek için docker'ı kullanmaya başladım, dosyaları kaplardan ileri geri kopyalamak için şunları yapabilirsiniz:

su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt

Bu txt içinde tanıdık bir dosya arayın ve kök ve voila olarak cd klasörüne sahip olacaksınız! istediğiniz her şeyi kopyalayın.

İçinde "birleştirilmiş" bir yol olabilir, sanırım içinde "diff" olanı istiyorum.

Ayrıca konteynırdan çıkar ve bıraktığınız yere geri dönmek isterseniz:

docker ps -a
docker start -i containerid

Sanırım böyle bir komutla hiçbir şey söylemediğinizde bu işe yarar

docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash

Kesinlikle hacker yöntemi ama ne olacak!


3
docker cp SRC_PATH CONTAINER_ID:DEST_PATH

Örneğin, xxxx / download / jenkins dosyamı tomcat'e kopyalamak istiyorum

Konteynır kimliğini almaya başladım Tomcat

docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
63686740b488        tomcat              "catalina.sh run"   12 seconds ago      Up 11 seconds       0.0.0.0:8080->8080/tcp   peaceful_babbage

docker cp xxxx/download/jenkins.war  63686740b488:usr/local/tomcat/webapps/

2

En sevdiğim yöntem:

KONTEYNER:

CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')

file.txt

mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt

veya

mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt

cihaz haritası yolu liman işçisi 1.6 ile fedora üzerinde çalışmıyor gibi görünüyor. Ayrı bir Q olarak koydunuz, stackoverflow.com/questions/29939419/… , herhangi bir yorum takdir edilecektir.
Yogesh_D

2

Bana göre, görüntünün içindeki dosyaları kopyalamak zorunda değilsiniz, ancak dosyalarınız için GIT veya SVN'yi kullanabilir ve ardından yerel bir klasörle senkronize edilmiş bir birim ayarlayabilirsiniz. Kapsayıcı çalıştırılırken, verilerin GIT deposundan kopyalanmıyorsa zaten yerel klasörde olup olmadığını kontrol edebilen bir komut dosyası kullanın. Bu, görüntünüzü çok hafif yapar.


Bu bir güvenlik riski ve erişim kabusu olmasını bekliyor gibi görünüyor. Git deposuna resminizden nasıl erişim sağlayabilirsiniz? Herkese açık bir depo olduğunu varsayarsak, konteynerinizin çalıştığı ana makinenin bu repoya erişimi olduğunu varsayarsınız.
tbm

Git docker konteynerinin içinde kullanılıyorsa size katılıyorum. Ancak bizim durumumuzda, komut dosyası ana bilgisayardan çalışıyor
h.aittamaa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.