我正在尝试为我们使用的Docker容器构建备份和还原解决方案。
我已创建了Docker基本映像ubuntu:base
,并且不希望每次都使用Docker文件重建它以向其添加文件。
我想创建一个从主机运行的脚本,并使用ubuntu:base
Docker镜像创建一个新容器,然后将文件复制到该容器中。
如何将文件从主机复制到容器?
答案 0 :(得分:2059)
cp
命令可用于复制文件。可以复制一个特定文件,如:
docker cp foo.txt mycontainer:/foo.txt
docker cp mycontainer:/foo.txt foo.txt
为了强调,mycontainer
是容器 ID,不 图像 ID。
文件夹src
包含的多个文件可以使用以下方式复制到target
文件夹中:
docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target
在1.8之前的Docker版本中,只能将文件从容器复制到主机。不是从主机到容器。
答案 1 :(得分:159)
获取容器名称或短容器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
答案 2 :(得分:125)
最干净的方法是在启动容器时在容器上安装主机目录:
{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 :(得分:108)
以下是一种相当丑陋的方式,但它有效。
docker run -i ubuntu /bin/bash -c 'cat > file' < file
答案 4 :(得分:39)
如果你需要在正在运行的容器上执行此操作,可以使用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
答案 5 :(得分:34)
解决方案如下:
root@123abc:/root# <-- get the container ID
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
该文件应直接复制到容器在文件系统上的位置。
答案 6 :(得分:28)
将文件复制到正在运行的容器中的另一种解决方案是使用tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
将文件foo.sh
复制到容器的/tmp
。
修改:删除reduntant -f
,感谢Maarten的评论。
答案 7 :(得分:28)
创建一个新的dockerfile并使用现有的图像作为基础。
FROM myName/myImage:latest
ADD myFile.py bin/myFile.py
然后构建容器:
docker build .
答案 8 :(得分:20)
将文件从主机复制到正在运行的容器
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH
基于Erik's answer以及Mikl&s和z0r的评论。
答案 9 :(得分:12)
这是直接回答问题&#39;将文件从主机复制到Docker容器&#39;在标题中提出这个问题。
试试docker cp
。这是最简单的方法,甚至可以在我的Mac上运行。用法:
docker cp /root/some-file.txt some-docker-container:/root
这会将主机上目录some-file.txt
中的文件/root
复制到名为some-docker-container
的Docker容器中/root
。它非常接近安全复制语法。如前一篇文章所示,您可以反过来使用它。即,您还将文件从容器复制到主机。
在您下载此信息之前,请输入docker cp --help
。阅读文档可能非常有用,有时候......
如果您不喜欢这种方式并且想要在已创建和运行的容器中使用数据量,那么娱乐是您今天唯一的选择。另请参阅 How can I add a volume to an existing Docker container? 。
答案 10 :(得分:12)
使用Docker 1.8,docker cp
能够将文件从主机复制到容器。请参阅Docker博客文章 Announcing Docker 1.8: Content Trust, Toolbox, and Updates to Registry and Orchestration 。
答案 11 :(得分:10)
我在这里尝试了大多数(upvoted)解决方案,但是在docker 17.09(2018年)中,不再有/ var / lib / docker / aufs文件夹。
这个简单的docker cp
解决了这个问题。
docker cp c:\path\to\local\file container_name:/path/to/target/dir/
如何获取container_name?
docker ps
有一个NAMES
部分。请勿使用IMAGE
。
答案 12 :(得分:9)
要在容器和本地文件系统之间复制文件/文件夹,请键入命令:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例如,
docker cp /home/foo container-id:/home/dir
要获取contianer id,请键入给定的命令:
docker ps
以上内容取自docker.com。
答案 13 :(得分:7)
假设容器已在运行,请键入给定的命令:
# 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 ...
注意:由于容器的用户与主机的用户不同,可能会出现权限问题。
答案 14 :(得分:6)
通常有三种类型:
从容器到主机
docker cp container_id:./bar/foo.txt .
从主机到容器
docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
从一个容器到另一个容器将1和2混合在一起
docker cp container_id1:./bar/foo.txt .
docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
答案 15 :(得分:6)
在docker环境中,所有容器都可以在目录中找到:
/var/lib/docker/aufs/required-docker-id/
要将源目录/文件复制到容器的任何部分,请键入给定的命令:
sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
答案 16 :(得分:6)
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中的copy命令。
我要复制一个名为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
答案 17 :(得分:4)
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
答案 18 :(得分:3)
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/
答案 19 :(得分:3)
如果主机是CentOS或Fedora,/var/lib/docker/aufs
中不存在代理,但它位于/proc
下:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
此cmd会将data
目录的所有内容复制到容器的/
,其ID为#34; containerid&#34;。
答案 20 :(得分:3)
您只需使用
跟踪本地计算机的IP地址即可ifconfig
然后只需进入Docker容器并输入
即可scp user_name@ip_address:/path_to_the_file destination
在任何情况下,如果您没有安装SSH客户端和服务器,只需使用以下命令安装:
sudo apt-get install openssh-server
答案 21 :(得分:3)
许多发现此问题的人实际上可能会遇到在创建文件时将文件复制到Docker图像的问题(我做过)。
在这种情况下,您可以使用COPY
中用于创建图像的Dockerfile
命令。
答案 22 :(得分:2)
有很好的答案,但太具体了。我发现docker ps
是获得您感兴趣的容器ID的好方法。然后执行
mount | grep <id>
查看卷的安装位置。这是
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
对我来说,但它可能是一个不同的路径,具体取决于操作系统和配置。现在只需将文件复制到该路径即可。
使用-v
并不总是切实可行。
答案 23 :(得分:2)
将文件复制到我找到的容器的最佳方法是使用docker run命令的-v
选项在主机上安装目录。
答案 24 :(得分:2)
如果像我这样的人不清楚@ h3nrik答案中的mycontainer
是什么意思,它实际上是容器ID。要将WarpSquare.mp4
中的文件/app/example_scenes/1440p60
从退出的Docker容器复制到当前文件夹,我使用了这个。
docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .
其中docker ps -q -l
提取上一个退出实例的容器ID。如果不是退出的容器,则可以通过docker container ls
或docker ps
答案 25 :(得分:2)
这是将数据从Docker复制到主机的命令:
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
以下是将数据从主机复制到docker的命令:
docker cp a.txt ccfbeb35116b:/home/
答案 26 :(得分:1)
这对我有用
#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
答案 27 :(得分:1)
如果使用Windows作为主机,您可以使用WinSCP连接到Docker并通过GUI传输文件。
如果在Linux上,scp
命令也可以通过终端工作。
答案 28 :(得分:1)
这是一个在运行tomcat容器时复制单个文件的在线程序。
docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat
这会将war文件复制到webapps目录,并立即让你的应用程序运行。
答案 29 :(得分:1)
我只是直接从容器所在的位置复制文件。
例如:
首先找出容器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
答案 30 :(得分:1)
Container Up语法:
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"
答案 31 :(得分:0)
我希望在没有 .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
。
答案 32 :(得分:0)
如果您能够使用容器注册表,那么 appendlayer 脚本可以满足您的要求:
假设 ubuntu:base
在注册表中已经可用。
然后,您可以使用脚本在其上添加由一些本地文件组成的新图层,将整个内容另存为新图像(即 ubuntu:test
)。
$ tar cvf - test.txt | python main.py <host> <repository> <old-tag> <new-tag>
无需重新构建,甚至无需将任何图像数据下载到本地计算机。
答案 33 :(得分:0)
真正的交易是:
docker volume create xdata
docker volume inspect xdata
所以你会看到它的挂载点目录。
只需将您的东西复制到那里
然后
docker run --name=example1 --mount source=xdata,destination=/xdata -it yessa bash
其中 yessa
是图像名称
答案 34 :(得分:0)
从容器复制到主机目录
docker cp [container-name/id]:./app/[index.js] index.js
(假设您已在dockerfile中创建了一个工作目录/ app)
从主机复制到容器
docker cp index.js [container-name/id]:./app/index.js
答案 35 :(得分:0)
最简单的方法是
docker cp <filename> <container-id>:<path>
答案 36 :(得分:0)
我刚刚开始使用docker来编译VLC,这是您可以从容器来回复制文件的操作:
roll(FromMinAndMax()
..min = 0
..max = 100
);
roll(FromList()
..pair = [0, 200]
);
在该txt中搜索一个熟悉的文件,您将拥有该文件夹,并以cd和root的身份访问cd!复制所有想要的内容。
可能其中包含“合并”的路径,我想您想要其中包含“ diff”的路径。
另外,如果您退出容器并想回到上次停站的地方,
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
我想当您未使用
这样的命令命名任何内容时,这很有用docker ps -a
docker start -i containerid
当然可以使用黑客方法!
答案 37 :(得分:0)
如果在Dockerfile中没有将目录定义为卷,则/ var / lib / docker / aufs / mnt //将起作用。但是有时容器中的目录被定义为卷。在这种情况下,aufs / mnt / * /下的内容和容器看到的内容是不同的。
您需要使用docker inspect检查容器,然后查找卷。你可以在那里找到类似/ var / lib / docker / vfs / dir / fe940b ...(id)的内容。您需要在此处添加/修改文件,而不是在aufs / mnt /*.
下令人困惑的部分是文件也出现在/ aufs / mnt / *下。我花了很长时间挠挠脑袋为什么这里的变化对我不起作用。希望这有助于某人。
答案 38 :(得分:0)
在我看来,您不必复制图像中的文件,但可以使用GIT或SVN作为文件,然后设置与本地文件夹同步的卷。在运行容器时使用脚本,该容器可以检查本地文件夹中是否已存在数据,如果不从GIT存储库复制它。这使你的图像非常轻量级。
答案 39 :(得分:0)
我通常使用此命令创建python服务器
python -m SimpleHTTPServer
在特定目录中,然后使用wget在docker中的所需位置传输文件。我知道这不是最好的方法,但我发现它更容易。
答案 40 :(得分:0)
我尝试过的一件事,它起作用了
启动Docker容器并在该容器下创建任何文件后;您可以从docker主机的以下位置轻松访问该文件: -
尝试一次!
答案 41 :(得分:0)
另一种解决方法是使用旧的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
答案 42 :(得分:0)
我最喜欢的方法:
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
答案 43 :(得分:0)
我会挂载然后用守护进程运行映像,就像这里给出的那样;
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
答案 44 :(得分:-4)
尝试docker cp
。
用法:
docker cp CONTAINER:PATH HOSTPATH
它将文件/文件夹从PATH
复制到HOSTPATH
。