Copying files from host to Docker container
我正在尝试为我们使用的Docker容器构建备份和恢复解决方案。
我有我创建的docker-base映像,
我想创建一个从主机运行的脚本,并使用
如何将文件从主机复制到容器?
可以使用
1 2 | docker cp foo.txt mycontainer:/foo.txt docker cp mycontainer:/foo.txt foo.txt |
对于Emphasis,
文件夹
1 2 | docker cp src/. mycontainer:/target docker cp mycontainer:/src/. target |
参考:用于
在1.8之前的Docker版本中,只能将文件从容器复制到主机。不是从主机到容器。
获取容器名称或短容器ID:
1 | $ docker ps |
获取完整容器ID:
1 | $ docker inspect -f '{{.Id}}' SHORT_CONTAINER_ID-or-CONTAINER_NAME |
复制文件:
1 | $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE |
例子:
1 2 3 4 5 6 7 | $ 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 |
或
1 2 3 4 5 | $ docker inspect -f '{{.Id}}' d8e703d7e303 d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5 $ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt |
最干净的方法是在启动容器时在容器上装载主机目录:
1 2 3 | {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 |
下面是一个相当丑陋的方法,但它是有效的。
1 | docker run -i ubuntu /bin/bash -c 'cat > file' < file |
如果需要在正在运行的容器上执行此操作,可以使用Docker Exec(在1.3中添加)。
首先,找到容器的名称或ID:
1 2 3 | $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b9b7400ddd8f ubuntu:latest "/bin/bash" 2 seconds ago Up 2 seconds elated_hodgkin |
在上面的示例中,我们可以使用
如果要将主机上的
1 2 | $ cd /tmp/somefiles $ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www |
然后我们可以在容器中执行
1 2 3 | $ docker exec -it elated_hodgkin /bin/bash root@b9b7400ddd8f:/# ls /var/www file1 file2 |
解决方案如下:
从船坞外壳,1 | root@123abc:/root# <-- get the container ID |
从主机
1 | cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root |
文件应直接复制到容器位于文件系统上的位置。
将文件复制到正在运行的容器中的另一个解决方案是使用tar:
1 | tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x |
将文件
编辑:删除reduntant
很容易
创建一个新的dockerfile并使用现有图像作为基础。
1 2 3 | FROM myName/myImage:latest ADD myFile.py bin/myFile.py |
然后构建容器:
1 | docker build . |
将文件从主机复制到正在运行的容器
1 | docker exec -i $CONTAINER /bin/bash -c"cat > $CONTAINER_PATH" < $HOST_PATH |
根据埃里克的回答和米克尔和Z0R的评论。
使用Docker 1.8,
这是对标题中此问题中提出的"将文件从主机复制到Docker容器"问题的直接回答。
试试
1 | docker cp /root/some-file.txt some-docker-container:/root |
这将把主机上目录
在你下载这篇文章之前,请输入
如果您不喜欢这种方式,并且您希望在已经创建并运行的容器中包含数据卷,那么娱乐是您今天唯一的选择。另请参见如何向现有Docker容器添加卷?.
我在这里尝试了大多数(投票)解决方案,但在Docker 17.09(2018年)中,不再有/var/lib/docker/aufs文件夹。
这个简单的
1 | docker cp c:\path\to\local\file container_name:/path/to/target/dir/ |
如何获取容器名称?
1 | docker ps |
有一个
要在容器和本地文件系统之间复制文件/文件夹,请键入以下命令:
1 | docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH} |
例如,
1 | docker cp /home/foo container-id:/home/dir |
要获取contianer ID,请键入给定的命令:
1 | docker ps |
以上内容摘自docker.com。
假设容器已经在运行,请键入给定的命令:
1 | # cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c"/bin/cat > /path/to/container/file" |
要使用共享目录共享文件,请通过键入给定命令来运行容器:
1 | # docker run -v /path/to/host/dir:/path/to/container/dir ... |
注意:由于容器的用户与主机的用户不同,可能会出现权限问题。
在Docker环境中,所有容器都位于以下目录中:
要将源目录/文件复制到容器的任何部分,请键入给定的命令:
通常有三种类型:
从容器到主机
1 | docker cp container_id:./bar/foo.txt . |
从主机到容器
1 | docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt |
从一个容器到一个容器混合1和2
1 2 3 | docker cp container_id1:./bar/foo.txt . docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt |
创建数据卷容器
1 | docker create --name dvc --volume /path/on/container cirros |
保留目录层次结构
1 | tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container |
检查你的工作
1 | docker run --rm --volumes-from dvc cirros ls -al /path/on/container |
如果主机是Centos或Fedora,则在
1 | cp -r /home/user/mydata/* /proc/$(docker inspect --format"{{.State.Pid}}" <containerid>)/root |
此命令将把
许多发现这个问题的人实际上可能有在创建文件时将其复制到Docker映像中的问题(我做过)。
在这种情况下,可以在用于创建图像的
请参阅文档。
您可以使用
1 | ifconfig |
然后进入你的码头集装箱,输入
1 | scp user_name@ip_address:/path_to_the_file destination |
在任何情况下,如果没有安装ssh客户机和服务器,只需使用以下方法安装:
1 | sudo apt-get install openssh-server |
这是将数据从Docker复制到主机的命令:
1 2 3 | docker cp container_id:file path/filename /hostpath docker cp a13fb9c9e674:/tmp/dgController.log /tmp/ |
下面是将数据从主机复制到Docker的命令:
1 | docker cp a.txt ccfbeb35116b:/home/ |
将文件复制到容器的最佳方法是使用docker run命令的
如果像我这样的人不清楚@h3nrik answer中的
1 | docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 . |
其中
有很好的答案,但太具体了。我发现
1 | mount | grep <id> |
查看卷的安装位置。那是
1 | /var/lib/docker/devicemapper/mnt/<id>/rootfs/ |
对我来说,这可能是一个不同的路径,这取决于操作系统和配置。现在只需将文件复制到该路径。
使用
我只需从主机直接复制容器所在位置的文件。
例如:
首先找出容器ID:
1 | root@**3aed62678d54**:/home# |
然后从主机中,假设文件在主目录中:
1 | root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/ |
回到容器…
1 | root@**3aed62678d54**:/home# ls cheering_nasa.gif |
容器向上语法:
1 | docker run -v /HOST/folder:/Container/floder |
码头工人档案
1 2 | COPY hom* /myFolder/ # adds all files starting with"hom" COPY hom?.txt /myFolder/ # ? is replaced with any single character, e.g.,"home.txt" |
这是用于在运行Tomcat容器时复制单个文件的联机程序。
1 | docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat |
这将把war文件复制到webapps目录,并让你的应用在短时间内运行。
如果使用Windows作为主机,您可以使用winscp连接到Docker并通过GUI传输文件。
如果在Linux上,
我最喜欢的方法:
容器:1 | CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}') |
TXT文件
1 | mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt |
或
1 | mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt |
我通常使用这个命令创建python服务器
python -m SimpleHTTPServer
在特定的目录中,然后使用wget将文件传输到docker中所需的位置。我知道这不是最好的方法,但我发现它容易得多。
如果在dockerfile中没有定义为卷的目录,那么/var/lib/docker/aufs/mnt/将起作用。但在某些情况下,容器中的目录被定义为卷。在这种情况下,aufs/mnt/*/下的内容和容器看到的内容是不同的。
您需要使用Docker Inspect检查集装箱,然后查找体积。在这里,您将看到一个关于/var/lib/docker/vfs/dir/fe940b等内容的提示…(身份证)。您需要在这里添加/修改文件,而不是在aufs/mnt/*下。
令人困惑的是,这些文件也出现在/aufs/mnt/*下。我花了很长时间在挠头,为什么这里的变化对我不起作用。希望这能帮助别人。
有一件事我试过了,它奏效了。
旋转Docker容器后,如果在该容器下创建任何文件,则可以从Docker主机的以下位置轻松访问该文件:
cd/var/lib/docker/aufs/containers/container_id/tmp尝试一次!
我刚开始使用Docker来编译VLC,下面是从容器中来回复制文件的方法:
1 2 3 | su - cd /var/lib/docker ls -palR > /home/user/dockerfilelist.txt |
在那个文本文件中搜索一个熟悉的文件,你就会得到文件夹,CD作为根目录,瞧!复制你想要的。
可能有一条路径中有"合并"的,我想您希望其中有"diff"的路径。
另外,如果您退出容器并想回到您离开的地方:
1 2 | docker ps -a docker start -i containerid |
我想当你没有用这样的命令来命名任何东西的时候这是有用的
1 | docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash |
当然是黑客的方法,但那又怎样呢?
我将装载并运行带有守护进程的映像,就像这里给出的一样;
1 | docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c"while true; do echo hello world; sleep 1; done" |
然后
1 | docker exec -it mntcontainer bash |
另一个解决方法是使用旧的好的
从主机运行:
1 2 | scp FILE_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH scp foo.txt 172.17.0.2:foo.txt |
如果需要复制目录:
1 2 | scp -r DIR_PATH_ON_YOUR_HOST IP_CONTAINER:DESTINATION_PATH scp -r directory 172.17.0.2:directory |
确保也将ssh安装到容器中。
1 | apt-get install openssh-server |
在我看来,您不必复制图像中的文件,但您可以对文件使用git或svn,然后设置与本地文件夹同步的卷。运行容器时使用一个脚本,该脚本可以检查本地文件夹中是否存在数据(如果不从Git存储库复制数据)。这让你的形象很轻。
试试
用途:
1 | docker cp CONTAINER:PATH HOSTPATH |
它将文件/文件夹从