将文件从主机复制到Docker容器
我正在尝试为我们使用的Docker容器构build一个备份和恢复解决scheme。
我有我创build的Docker基础镜像, ubuntu:base
,并且不希望每次都使用Docker文件重新构build它以向其中添加文件。
我想创build一个从主机运行的脚本,并使用ubuntu:base
Docker镜像创build一个新容器,然后将文件复制到该容器中。
我怎样才能从主机上的文件复制到容器?
cp
命令可以用于这个。 例如:
docker cp foo.txt mycontainer:/foo.txt docker cp mycontainer:/foo.txt foo.txt
参考: 用于cp
Docker CLI文档
请注意,docker cp在Docker 1.8中并不新鲜。 在旧版本的Docker中,docker cp命令只允许将文件从容器复制到主机
-
获取容器名称或简短的容器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 exec(在1.3中添加)。
首先,find容器的名称或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
并validation它是否工作:
$ docker exec -it elated_hodgkin /bin/bash root@b9b7400ddd8f:/# ls /var/www file1 file2
解决scheme如下,
从Docker shell中,
root@123abc:/root# <-- get the container ID
从主机
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
文件应该直接复制到容器位于文件系统的位置。
将文件复制到正在运行的容器的另一个解决scheme是使用tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
将文件foo.sh
复制到容器的/tmp
中。
编辑:删除reduntant -f
,感谢Maarten的评论。
从主机复制文件到正在运行的容器
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH
根据Erik的回答和Mikl和z0r的评论。
好简单
-
创build一个新的dockerfile并使用现有的图像作为您的基础。
FROM myName/myImage:latest ADD myFile.py bin/myFile.py
-
然后build立容器:
docker build .
使用Docker 1.8, docker cp
能够将文件从主机复制到容器。 查看Docker博客发布Docker 1.8:内容信任,工具箱和registry和编排更新 。
这是对标题中的问题“在主机中复制文件到Docker容器”的直接回答。
尝试docker cp
。 这是最简单的方法,即使在我的Mac上也可以工作。 用法:
docker cp /root/some-file.txt some-docker-container:/root
这会将主机上目录/root
的文件some-file.txt
复制到名为some-docker-container
的Docker容器some-docker-container
放到目录/root
。 它非常接近安全复制语法。 如前一篇文章所示,反之亦然。 也就是说,您也将容器中的文件复制到主机。
在你下传这篇文章之前,请inputdocker cp --help
。 阅读文档可能会非常有帮助,有时候…
如果您不喜欢这种方式,并且希望在已经创build并正在运行的容器中使用数据卷,那么今天的娱乐是您唯一的select。 另请参见如何将卷添加到现有的Docker容器? 。
假设容器已经在运行,input给定的命令:
# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"
要使用共享目录共享文件,请input给定的命令来运行容器:
# docker run -v /path/to/host/dir:/path/to/container/dir ...
注意:由于容器的用户与主机的用户不一样,可能会出现权限问题。
在docker环境中,所有容器都在以下目录中:
/var/lib/docker/aufs/required-docker-id/
要将源目录/文件复制到容器的任何部分,请键入给定的命令:
sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
您可以使用追踪本地机器的IP地址
ifconfig
然后进入你的Docker容器并input
scp user_name@ip_address:/path_to_the_file destination
无论如何,如果您没有安装SSH客户端和服务器,只需使用以下命令进行安装:
sudo apt-get install openssh-server
要在容器和本地文件系统之间复制文件/文件夹,请键入以下命令:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例如,
docker cp /home/foo container-id:/home/dir
要获得contianer id,请键入给定的命令:
docker ps
以上内容摘自docker.com 。
tar
和docker cp
是一个很好的组合复制目录中的一切。
创build一个数据卷容器
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
将文件复制到容器的最佳方法是使用docker run命令的-v
选项在主机上挂载一个目录。
有很好的答案,但太具体。 我发现docker ps
是获得你感兴趣的容器id的好方法
mount | grep <id>
查看卷的安装位置。 那是
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
对我来说,但它可能是一个不同的path取决于操作系统和configuration。 现在只需将文件复制到该path。
使用-v
并不总是可行的。
许多人发现这个问题可能实际上有复制文件到Docker镜像的过程中 (我做了)的问题。
在这种情况下,您可以在用于创build映像的Dockerfile
中使用COPY
命令。
请参阅文档 。
如果主机是CentOS或Fedora,则在/var/lib/docker/aufs
有一个代理NOT,但它位于/proc
:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
这个cmd会将data
目录的所有内容复制到id为“containerid”的容器的/
。
如果使用Windows作为主机,您可以使用WinSCP连接到Docker并通过GUI传输文件。
如果在Linux上, scp
命令也可以通过terminal工作。
如果在Dockerfile中没有将目录定义为卷,则/ var / lib / docker / aufs / mnt将会工作。 但有些情况下容器中的目录被定义为一个卷。 在这种情况下,aufs / mnt / * /下的内容和容器看到的内容是不同的。
您将需要使用docker检查检查容器,然后查找容量。 在那里你会发现像/ var / lib / docker / vfs / dir / fe940b …(id)。 您将需要在这里添加/修改文件,而不是在aufs / mnt / *下。
令人困惑的是,这些文件也出现在/ aufs / mnt / *下。 我花了一段时间挠了挠头,为什么这里的变化不适合我。 希望这有助于某人。
我最喜欢的方法:
容器:
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
要么
mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt
我会安装,然后运行一个守护进程的形象,只是在这里给出的任何东西;
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
我直接从主机上直接从容器所在的位置复制文件。
例如:
先找出容器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
我尝试过的一件事情,它的工作
一旦你启动你的docker集装箱,并且如果你在该容器下创build任何文件, 您可以轻松地从Docker主机的以下位置访问该文件: –
cd / var / lib / docker / aufs / containers / container_id / tmp
尝试一次!
这是运行tomcat容器时复制单个文件的在线人员。
docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat
这将复制战争文件到webapps目录,让您的应用程序运行在任何时候。
尝试docker cp
。
用法:
docker cp CONTAINER:PATH HOSTPATH
它将文件/文件夹从PATH
复制到HOSTPATH
。