在Docker中将数据添加到现有命名卷的正确方法是什么?


88

我以旧的方式使用Docker和卷容器:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

但是现在我通过创建命名卷更改为新方法:

 docker volume create --name my-jenkins-volume 

我将此新卷绑定到新的Jenkins容器。我只剩下一个文件夹,其中有/var/jenkins_home我以前的jenkins容器的文件夹。(通过使用docker cp)现在,我要用该文件夹的内容填充新的命名卷。

我可以复制该文件夹的内容到/var/lib/jenkins/volume/my-jenkins-volume/_data吗?

Answers:


134

可以数据无疑直接复制到/var/lib/docker/volumes/my-jenkins-volume/_data,但这样做你:

  • 依靠对Docker主机的物理访问。如果您正在与远程docker API进行交互,则此技术将无效。

  • 将来,依赖于卷实现的特定方面可能会发生变化,从而破坏您依赖它的任何流程。

我认为您最好依靠命令行客户端使用docker api可以完成的事情。最简单的解决方案可能只是使用一个辅助容器,例如:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper

3
关于第二个项目符号,您可以运行docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'以编程方式获取其实际位置。仍然感觉不是一个好主意。
c24w

8
该辅助容器永远不需要实际运行。只需创建它,然后运行docker cp然后将其删除就足够了。
亚历克斯(Alex)

您无法执行到该容器中以查看结果或手动修改文件。
CodeOrElse '18年

3
请注意,/var/lib/docker/volumes/my-jenkins-volume/_dataMac上使用Docker时,列出文件无效,因为文件存储在xhyve虚拟机内部。参见forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni,


32

您可以使用以下方法将接受的答案缩小为一行:

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data

1
我想知道/ tmp的瞬态特性是否会带来风险,即在cp完成之前容器可能会删除您的数据?pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES

1
该链接并没有真正阐明/ tmp中文件的生存期。我指出:“程序不得假定在两次调用程序之间都保留了/ tmp中的任何文件或目录。” 这意味着文件将继续存在,但这是一种保证。如果docker的-v选项不存在,它将在容器中创建一个目录,因此,如果您担心这种潜在的竞争状况,将/ tmp / src更改为/ src将会起作用。由于没有缺点,我将编辑答案以反映这一点。
headdab

3
并不-v `pwd`:/src意味着该命令正在主机上运行?(pwd例如,如果主机是另一台计算机,主机如何映射?-不能。)如果docker命令未在主机上运行,​​则此命令将无效。我相信这就是为什么我们有docker cp。看来这不是docker的“方式”-这只是一种特殊情况,仅当docker命令在主机上运行时才起作用。我理解正确吗?
Wyck

是的,我认为您是对的。 pwd必须解析为主机上的文件。来自docker的安装文档:“对于绑定安装,第一个字段是主机上文件或目录的路径。”
headdab '18 -10-2

1
因此,这不起作用复制你的本地文件放入容器如果在远程主机上,因为你安装pwd它甚至不需要在远程主机存在。取而代之的是Dmytro Melnychuk(create + cp + rm)的解决方案会将本地副本复制到容器中,无论它在哪里运行。
哈维·蒙特罗

25

您无需启动某个容器即可将数据添加到已经存在的命名卷中,只需创建一个容器并在其中复制数据即可:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp

2
如果不真正需要busybox的内容;您可以使用hello-world它,它也可以工作。busybox是1.22MB。取而代之的hello-world是13.3kB。问题是:以同样的方式可以从头开始创建Dockerfile,是否可以只用“装载”卷而不用启动容器来做“无”映像的“ docker容器创建”?
哈维·蒙特罗

1
该解决方案获得最高投票+1,但正确的语法docker cpdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

3

以下是将〜/ data的内容复制到名为my-vol的Docker卷的步骤

步骤1.将卷附加到“临时”容器。对于在终端中运行的命令:

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

步骤2.将〜/ data的内容复制到my-vol中。为此,在新的终端窗口中运行以下命令:

cd ~/data docker cp . alpine:/data

这会将〜/ data的内容复制到my-vol卷中。复制后退出临时容器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.