我正在尝试为我们使用的Docker容器构建备份和还原解决方案。
我已经创建了Docker基本映像ubuntu:base
,并且不想每次都使用Docker文件重建它来向其添加文件。
我想创建一个从主机运行的脚本,并使用ubuntu:base
Docker映像创建一个新容器,然后将文件复制到该容器中。
如何将文件从主机复制到容器?
我正在尝试为我们使用的Docker容器构建备份和还原解决方案。
我已经创建了Docker基本映像ubuntu:base
,并且不想每次都使用Docker文件重建它来向其添加文件。
我想创建一个从主机运行的脚本,并使用ubuntu:base
Docker映像创建一个新容器,然后将文件复制到该容器中。
如何将文件从主机复制到容器?
Answers:
该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版本中,只能将文件从容器复制到主机。不是从主机到容器。
docker cp
从容器复制到主机的效果很好,但是当使用它将文件从主机复制到容器时,没有效果……有人知道为什么吗?docker版本:Docker版本1.10.3,内部版本cb079f6-unsupported
获取容器名称或简短的容器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
aufs
一个devicemapper
。检查容器安装路径(运行时)的最简单方法是运行command mount
。
/var/lib/docker/aufs/diff/<id>/
/var/lib
适合我。find / -name docker
也没有帮助。
最干净的方法是在启动容器时在容器上挂载主机目录:
{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 -d -p -v /host/path:/mnt --name container_name image_name
docker cp
是单向手术!
以下是执行此操作的相当难看的方法,但它可以工作。
docker run -i ubuntu /bin/bash -c 'cat > file' < file
docker commit `docker ps -l -q` ubuntu-with-file
。否则更改将丢失(使用您想要的任何名称代替ubuntu-with-file
)
docker exec
功能来运行容器:docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
docker exec -i ...
代替@Mikl -it
,因为从文件管道输入时没有TTY。
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 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
该文件应直接复制到容器在文件系统上的位置。
通常有三种类型:
从容器到主机
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
将文件复制到正在运行的容器中的另一种解决方案是使用tar:
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
将文件复制foo.sh
到/tmp
容器中。
编辑:删除多余的-f
,感谢Maarten的评论。
-f -
有点多余,虽然,默认行为是编写反正到标准输出。
使用Docker 1.8,docker cp
能够将文件从主机复制到容器。请参阅Docker博客文章“ 宣布Docker 1.8:内容信任,工具箱以及注册表和业务流程的更新”。
docker cp foo.txt mycontainer:/foo.txt
这是标题中此问题中提出的“将文件从主机复制到Docker容器中”问题的直接答案。
尝试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
。有时,阅读文档可能会很有帮助。
如果您不喜欢这种方式,并且想要在已创建并正在运行的容器中存储数据量,那么,重新创建是当今唯一的选择。另请参阅如何将卷添加到现有Docker容器中?。
要在容器和本地文件系统之间复制文件/文件夹,请键入以下命令:
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例如,
docker cp /home/foo container-id:/home/dir
要获取容器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 exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
cat
退出后不会终止。如果对您来说很重要(如果要复制bash脚本,bash将拒绝运行它们),则应运行lsof | grep yourfilename
并杀死cat
保存所述文件的进程。
kill $(lsof | grep /path/to/file | sed ...)
。我会在你们的帮助表示感谢
kill $(docker top CONTAINERNAME | sed -n '/cat$/p' | sed 's/^root[^0-9]\+\([0-9]\+\).*$/\1/')
如果主机是CentOS或Fedora,则在中有一个NOT代理/var/lib/docker/aufs
,但该代理位于/proc
:
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
此cmd会将data
目录的所有内容复制到/
ID为“ containerid”的容器中。
/proc
)。还要扩展路径以将文件放置在其他位置,而不仅仅是根目录。
万一像我这样的人不清楚mycontainer
@ h3nrik答案中的含义,它实际上是容器ID。要复制文件WarpSquare.mp4
在/app/example_scenes/1440p60
从激发泊坞窗容器当前文件夹我用这个。
docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .
在其中docker ps -q -l
拉出最后一个退出实例的容器ID。如果它不是已退出的容器,则可以通过docker container ls
或获取它docker ps
docker ps -a
或列出已退出容器的ID docker container ls -a
。
您可以使用以下命令跟踪本地计算机的IP地址
ifconfig
然后进入您的Docker容器并输入
scp user_name@ip_address:/path_to_the_file destination
无论如何,如果您没有安装SSH客户端和服务器,只需使用以下命令进行安装:
sudo apt-get install openssh-server
这是一个在线程序,用于在运行tomcat容器时复制单个文件。
docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat
这会将war文件复制到webapps目录,并使您的应用立即运行。
容器启动语法:
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"
将文件复制到我发现的容器的最好方法是使用-v
docker run命令选项在主机上安装目录。
我刚刚开始使用docker编译VLC,这是您可以从容器来回复制文件的操作:
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
在该txt中搜索一个熟悉的文件,您将拥有该文件夹,并以root和voila的身份访问cd!复制所有您想要的。
可能其中包含“合并”的路径,我想您想要其中包含“ diff”的路径。
另外,如果您退出容器并想回到上次停靠的地方:
docker ps -a
docker start -i containerid
我想这在您未使用以下命令命名时很有用
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
当然可以使用黑客方法,但是怎么办!
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/
我最喜欢的方法:
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
我认为您不必复制映像中的文件,但可以对文件使用GIT或SVN,然后设置与本地文件夹同步的卷。运行容器时使用脚本,该脚本可以检查本地文件夹中是否已存在数据(如果未从GIT存储库中复制数据)。这使您的图像非常轻巧。