[英]How to copy files from host to Docker container?
我正在嘗試為我們使用的 Docker 容器構建備份和恢復解決方案。
我有我創建的 Docker 基礎映像ubuntu:base
,並且不想每次都使用 Docker 文件重新構建它以向其中添加文件。
我想創建一個從主機運行的腳本,並使用ubuntu:base
Docker 映像創建一個新容器,然后將文件復制到該容器中。
如何將文件從主機復制到容器?
cp
命令可用於復制文件。
可以將一個特定文件復制到容器中,例如:
docker cp foo.txt container_id:/foo.txt
可以從容器中復制一個特定文件,例如:
docker cp container_id:/foo.txt foo.txt
為了強調, container_id
是容器ID,而不是圖像ID。 (使用docker ps
查看包含container_id
的列表。)
文件夾src
包含的多個文件可以使用以下命令復制到target
文件夾中:
docker cp src/. container_id:/target
docker cp container_id:/src/. target
在 1.8 之前的 Docker 版本中,只能將文件從容器復制到主機。 不是從主機到容器。
獲取容器名稱或短容器 ID:
$ docker ps
獲取完整的容器 ID:
$ docker inspect -f '{{.Id}}' SHORT_CONTAINER_ID-or-CONTAINER_NAME
拷貝文件:
$ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
$ 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
或者
$ docker inspect -f '{{.Id}}' d8e703d7e303
d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5
$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt
最干凈的方法是在啟動容器時在容器上掛載一個主機目錄:
{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
以下是一種相當丑陋的方法,但它有效。
docker run -i ubuntu /bin/bash -c 'cat > file' < file
通常有以下三種類型:
從容器到主機
docker cp container_id:./bar/foo.txt .
docker cp
命令也可以雙向工作。
從主機到容器
docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
從主機復制到容器的第二種方法:
docker cp foo.txt mycontainer:/foo.txt
從一個容器到一個容器混合 1 和 2
docker cp container_id1:./bar/foo.txt . docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
如果您需要在正在運行的容器上執行此操作,您可以使用 docker exec(在 1.3 中添加)。
首先,找到容器的名稱或 ID:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9b7400ddd8f ubuntu:latest "/bin/bash" 2 seconds ago Up 2 seconds elated_hodgkin
在上面的示例中,我們可以使用b9b7400ddd8f
或elated_hodgkin
。
如果您想將主機上/tmp/somefiles
中的所有內容復制到容器中的/var/www
中:
$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www
然后我們可以在容器中執行/bin/bash
並驗證它是否有效:
$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1 file2
創建一個新的 dockerfile 並使用現有的圖像作為您的基礎。
FROM myName/myImage:latest ADD myFile.py bin/myFile.py
然后構建容器:
docker build .
解決方案如下,
root@123abc:/root# <-- get the container ID
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
該文件應直接復制到容器位於文件系統上的位置。
將文件復制到正在運行的容器中的另一種解決方案是使用 tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
將文件foo.sh
復制到容器的/tmp
中。
編輯:刪除冗余-f
,感謝Maarten的評論。
將文件從主機復制到正在運行的容器
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH
基於Erik 的回答以及 Mikl 和 z0r 的評論。
這是對標題中這個問題中提出的“將文件從主機復制到 Docker 容器”問題的直接回答。
嘗試docker cp
。 這是最簡單的方法,甚至可以在我的 Mac 上使用。 用法:
docker cp /root/some-file.txt some-docker-container:/root
這會將主機上/root
目錄中的文件some-file.txt
復制到名為some-docker-container
的 Docker 容器中的目錄/root
中。 它非常接近安全復制語法。 如上一篇文章所示,您可以反之亦然。 即,您還將文件從容器復制到主機。
在你下載這篇文章之前,請輸入docker cp --help
。 閱讀文檔可能會很有幫助,有時...
如果您不喜歡這種方式,並且希望在您已經創建和運行的容器中存儲數據量,那么娛樂是您今天唯一的選擇。 另請參閱如何將卷添加到現有 Docker 容器? .
我在這里嘗試了大多數(贊成的)解決方案,但在 docker 17.09(2018 年)中不再有 /var/lib/docker/aufs 文件夾。
這個簡單的docker cp
解決了這個任務。
docker cp c:\path\to\local\file container_name:/path/to/target/dir/
如何獲取容器名稱?
docker ps
有一個NAMES
部分。 不要使用IMAGE
。
使用 Docker 1.8, docker cp
能夠將文件從主機復制到容器。 請參閱 Docker 博客文章宣布 Docker 1.8:內容信任、工具箱以及對注冊表和編排的更新。
要在容器和本地文件系統之間復制文件/文件夾,請鍵入命令:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例如,
docker cp /home/foo container-id:/home/dir
要獲取 contianer id,請鍵入給定的命令:
docker ps
以上內容取自docker.com 。
假設容器已經在運行,輸入給定的命令:
# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"
要使用共享目錄共享文件,請通過鍵入給定命令運行容器:
# docker run -v /path/to/host/dir:/path/to/container/dir ...
注意:由於容器的用戶與主機的用戶不同,因此可能會出現權限問題。
這是將數據從 Docker 復制到主機的命令:
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
以下是將數據從主機復制到 docker 的命令:
docker cp a.txt ccfbeb35116b:/home/
在 docker 環境中,所有容器都在目錄中:
/var/lib/docker/aufs/required-docker-id/
要將源目錄/文件復制到容器的任何部分,請鍵入給定的命令:
sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
容器向上語法:
docker run -v /HOST/folder:/Container/floder
在 docker 文件中
COPY hom* /myFolder/ # adds all files starting with "hom"
COPY hom?.txt /myFolder/ # ? is replaced with any single character, e.g., "home.txt"
Docker cp 命令是一個方便的實用程序,允許在容器和主機系統之間復制文件和文件夾。
如果要將文件從主機系統復制到容器,則應使用 docker cp 命令,如下所示:
docker cp host_source_path container:destination_path
首先使用 docker ps 命令列出正在運行的容器:
abhishek@linuxhandbook:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
8353c6f43fba 775349758637 "bash" 8 seconds ago Up 7
seconds ubu_container
您需要知道容器 ID 或容器名稱。 在我的例子中,docker 容器名稱是 ubu_container。 容器 ID 為 8353c6f43fba。
如果要驗證文件是否復制成功,可以通過以下方式進入容器,然后使用常規 Linux 命令:
docker exec -it ubu_container bash
將文件從主機系統復制到 docker 容器 使用 docker cp 進行復制類似於 Linux 中的復制命令。
我將復制一個名為 a.py 的文件到容器中的 home/dir1 目錄。
docker cp a.py ubu_container:/home/dir1
如果文件被成功復制,您將不會在屏幕上看到任何輸出。 如果目標路徑不存在,您會看到一個錯誤:
abhishek@linuxhandbook:~$ sudo docker cp a.txt ubu_container:/home/dir2/subsub
Error: No such container:path: ubu_container:/home/dir2
如果目標文件已經存在,它將被覆蓋而沒有任何警告。
您也可以使用容器 ID 代替容器名稱:
docker cp a.py 8353c6f43fba:/home/dir1
如果主機是 CentOS 或 Fedora,則/var/lib/docker/aufs
中沒有代理,但它在/proc
下:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
此 cmd 會將data
目錄的所有內容復制到 ID 為“containerid”的容器的/
中。
tar
和docker cp
是復制目錄中所有內容的好組合。
創建數據卷容器
docker create --name dvc --volume /path/on/container cirros
保留目錄層次結構
tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container
檢查你的工作
docker run --rm --volumes-from dvc cirros ls -al /path/on/container
如果像我這樣的人不清楚@ mycontainer
答案中的 mycontainer 是什么意思,它實際上是容器 ID。 要將/app/example_scenes/1440p60
中的文件WarpSquare.mp4
從退出的 docker 容器復制到當前文件夾,我使用了這個。
docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .
其中docker ps -q -l
提取最后一個退出實例的容器 ID。 如果它不是已退出的容器,您可以通過docker container ls
或docker ps
獲取它
docker cp SRC_PATH CONTAINER_ID:DEST_PATH
例如,我想將我的文件 xxxx/download/jenkins 復制到 tomcat
我開始獲取容器 Tomcat 的 id
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/
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
目標路徑必須預先存在
這是一個用於在運行 tomcat 容器時復制單個文件的在線工具。
docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat
這會將戰爭文件復制到 webapps 目錄並立即讓您的應用程序運行。
將文件復制到我發現的容器的最佳方法是使用 docker run 命令的-v
選項在主機上安裝目錄。
有很好的答案,但太具體了。 我發現docker ps
是獲取您感興趣的容器 id 的好方法。然后執行
mount | grep <id>
查看卷的安裝位置。 那是
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
對我來說,但它可能是不同的路徑,具體取決於操作系統和配置。 現在只需將文件復制到該路徑。
使用-v
並不總是實用的。
我最喜歡的方法:
CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')
mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt
或者
mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
我剛開始使用 docker 編譯 VLC,以下是從容器中來回復制文件的方法:
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
在該 txt 中搜索一個熟悉的文件,您將擁有該文件夾,以 root 身份 cd 到它,瞧! 復制所有你想要的。
可能有一條帶有“合並”的路徑,我猜你想要一條帶有“差異”的路徑。
此外,如果您退出容器並想回到您離開的地方:
docker ps -a
docker start -i containerid
我想當你沒有用類似的命令命名任何東西時這很有用
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
當然是黑客方法,但那又怎樣!
這對我有用
#Run the docker image in detached mode
$docker run -it -d test:latest bash
$ docker ps
CONTAINER ID IMAGE COMMAND
a6c1ff6348f4 test:latest "bash"
#Copy file from host to container
sudo docker cp file.txt a6c1ff6348f4:/tmp
#Copy the file from container to host
docker cp test:/tmp/file.txt /home
您可以使用跟蹤本地計算機的 IP 地址
ifconfig
然后只需進入您的 Docker 容器並輸入
scp user_name@ip_address:/path_to_the_file destination
在任何情況下,如果您沒有安裝 SSH 客戶端和服務器,只需使用以下命令安裝它:
sudo apt-get install openssh-server
在我看來,您不必在圖像中復制文件,但您可以使用 GIT 或 SVN 保存文件,然后設置與本地文件夾同步的卷。 在運行容器時使用腳本,如果不從 GIT 存儲庫復制數據,則該腳本可以檢查本地文件夾中是否已存在數據。 這使您的圖像非常輕巧。
我希望在沒有像.git
文件夾這樣的文件的情況下在容器中進行構建過程,但是當我以交互方式運行容器來調試問題時,我想要這些文件。 就像 Ben Davis 的回答一樣,這會在容器內執行文件副本。 但是我不想在進入容器時自己實際運行該命令。 因此,以下腳本可以解決問題:
# mount the current [project] directory as read only
docker run --name my_container -v $(pwd):/mnt/application:ro -itd my_image /bin/bash
# copy the missing project files from the mounted directory
docker exec -it my_container /bin/bash -c 'cp -rnT /mnt/application $HOME/application'
# interactively use the container
docker attach my_container
這留下了一個my_container
容器實例。 要再次運行該命令,您必須編寫docker rm my_container
。 或者,如果您想再次進入該容器實例,您可以執行docker start my_container && docker attach my_container
。
注意cp -n
標志,如果文件已經存在於目標中,它會防止覆蓋文件。 :ro
部分不允許更改主機文件。 您可以將$(pwd)
更改為特定目錄,例如/home/user/dev/application
。
您可以使用以下命令
將文件從主機復制到 docker 容器
docker cp /hostfile container_id:/to_the_place_you_want_the_file_to_be
將文件從 docker 容器復制到主機
docker cp container_id:src_path to_the_place_you_want_the_file_to_be
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
從主機復制到容器。
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
從容器復制到主機。
如果您沒有在 Dockerfile 中將目錄定義為卷,則 /var/lib/docker/aufs/mnt// 將起作用。 但是在某些情況下,容器內的目錄被定義為一個卷。 這種情況下aufs/mnt/*/下的內容和容器看到的內容是不一樣的。
您需要使用 docker inspect 檢查容器,然后查找卷。 在那里你會發現類似 /var/lib/docker/vfs/dir/fe940b... (id)的提及。 您需要在此處添加/修改文件,而不是在 aufs/mnt/* 下。
令人困惑的部分是這些文件也出現在 /aufs/mnt/* 下。 我花了很長時間摸不着頭腦,為什么這里的更改對我不起作用。 希望這可以幫助某人。
嘗試docker cp
。
用法:
docker cp CONTAINER:PATH HOSTPATH
它將文件/文件夾從PATH
復制到HOSTPATH
。
我會掛載然后使用守護進程運行映像,就像這里給出的一樣;
docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
然后
docker exec -it mntcontainer bash
另一種解決方法是使用舊的scp
。 這在您需要復制目錄的情況下很有用。
從您的主機運行:
scp FILE_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt
如果您需要復制目錄:
scp -r DIR_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory
確保也將 ssh 安裝到您的容器中。
apt-get install openssh-server
如果使用 Windows 作為主機,您可以使用WinSCP連接到 Docker 並通過 GUI 傳輸文件。
如果在 Linux 上, scp
命令也可以通過終端運行。
我嘗試過的一件事,它奏效了
一旦你啟動了你的 docker 容器,如果你在那個容器下創建了任何文件; 您可以從 docker 主機的以下位置輕松訪問該文件:-
試一次!
實現這一目標的最簡單方法是,
docker cp <filename> <container-id>:<path>
我只是從主機上直接從容器所在的位置復制文件。
例如:
首先找出容器id:
root@**3aed62678d54**:/home#
然后從主機,假設文件在主目錄中:
root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/
回到容器...
root@**3aed62678d54**:/home# ls cheering_nasa.gif
我通常使用這個命令創建 python 服務器
python -m SimpleHTTPServer
在特定目錄中,然后只需使用 wget 在 docker 中的所需位置傳輸文件。 我知道這不是最好的方法,但我發現它更容易。
從容器復制到主機目錄
docker cp [container-name/id]:./app/[index.js] index.js
(假設您在 dockerfile 中創建了一個 workdir /app)
從主機復制到容器
docker cp index.js [container-name/id]:./app/index.js
真正的交易是:
docker volume create xdata
docker volume inspect xdata
所以你會看到它的安裝點目錄。
把你的東西復制到那里
然后
docker run --name=example1 --mount source=xdata,destination=/xdata -it yessa bash
其中yessa
是圖像名稱
如果您能夠使用容器注冊表,則appendlayer Python 包可以滿足您的要求:
假設ubuntu:base
在注冊表中已經可用。
然后,您可以使用腳本在其上添加由一些本地文件組成的新層,將整個內容保存為新圖像(即ubuntu:test
)。
$ pip install appendlayer
$ tar cvf - test.txt | appendlayer <host> <repository> <old-tag> <new-tag>
所有這些都無需重建甚至將任何圖像數據下載到您的本地計算機。
從容器外部使用以下命令,我能夠將文件從主機復制到容器。
487b00c94dd4 = Container ID
D:\demo\demo.tar= Source Url
/myfolder= Container Url
docker cp "D:\demo\demo.tar" 487b00c94dd4:/myfolder
有時對 shell 啟動執行單獨的交互式命令很麻煩。 當我想將一個點文件復制到我的容器中時,我會這樣做,這樣我的 shell 將包含我的自定義項
docker exec -u root -it mycontainername bash -c "echo "$(cat ~/.bashrc | base64 -w 0)" | base64 --decode > /tmp/.bashrc_inside_container; bash --rcfile /tmp/.bashrc_inside_container"
我強烈建議您不要將任何文件復制到任何容器,而是使用 docker 卷。 這將允許您將文件保存在主機上。 如果您不這樣做,那么當升級您的 docker 映像/容器時(您應該在包含任何 CVE 的任何版本上執行此操作),那么您將刪除剛剛上傳的文件。
我 SFTP 到我的 Docker 主機(通常是 Linux 服務器),在那里上傳文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.