如何在构build期间将主机卷装入Dockerfile的Docker容器中

原始问题:如何在Dockerfile中使用VOLUME指令?

修改:从下面的答案更新,所以我想要解决的实际问题是 – 如何在生成期间将主机卷装入Dockerfile中的Docker容器中,即在docker生成过程中让docker docker run -v /export:/exportfunction。

最新更新:现在有一个解决scheme。 虽然它不是严格的Docker,但是“ 它解决了Dockerfile的所有弱点 ”,所以我认为它是完美的答案。 检查我的最新答案的细节。

更新:所以答案是“不可能的”。 我可以接受它作为答案,因为我知道这个问题已经在https://github.com/docker/docker/issues/3156广泛讨论。 我可以理解,对于docker开发人员来说,可移植性是一个至关重要的问题。 但作为docker用户,我不得不说我对这个缺失的function感到非常失望。 让我用前面提到的讨论引用我的观点:“ 我想使用Gentoo作为基础映像,但是一旦映像build立完成后,绝对不希望Portage树数据在任何层中。如果不是在安装过程中出现在镜像中的巨大的portage树,可能会有一些不错的容器。 “是的,我可以使用wget或curl来下载我需要的任何东西,但是仅仅是一个可移植性的考虑现在迫使我下载> 1GB的Portage树,每次构buildGentoo基础映像既不高效,也不便于用户使用。 此外,软件包仓库将总是在/ usr / portage下,因此在Gentoo下永远都是可移植的。 再一次,我尊重这个决定,但同时也请允许我expression我的失望。 谢谢。

原始问题的细节:

通过卷共享目录
http://docker.readthedocs.org/en/v0.7.3/use/working_with_volumes/

它说数据卷function“从Docker Remote API的第一版开始就可用”。 我的docker是版本1.2.0,但我发现上面的文章中给出的例子不工作:

 # BUILD-USING:        docker build -t data . # RUN-USING:          docker run -name DATA data FROM          busybox VOLUME        ["/var/volume1", "/var/volume2"] CMD           ["/usr/bin/true"] 

在Dockerfile中通过VOLUME命令将主机安装的卷挂载到docker容器中的正确方法是什么?

 $ apt-cache policy lxc-docker lxc-docker: Installed: 1.2.0 Candidate: 1.2.0 Version table: *** 1.2.0 0 500 https://get.docker.io/ubuntu/ docker/main amd64 Packages 100 /var/lib/dpkg/status $ cat Dockerfile FROM debian:sid VOLUME ["/export"] RUN ls -l /export CMD ls -l /export $ docker build -t data . Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM debian:sid ---> 77e97a48ce6a Step 1 : VOLUME ["/export"] ---> Using cache ---> 59b69b65a074 Step 2 : RUN ls -l /export ---> Running in df43c78d74be total 0 ---> 9d29a6eb263f Removing intermediate container df43c78d74be Step 3 : CMD ls -l /export ---> Running in 8e4916d3e390 ---> d6e7e1c52551 Removing intermediate container 8e4916d3e390 Successfully built d6e7e1c52551 $ docker run data total 0 $ ls -l /export | wc 20 162 1131 $ docker -v Docker version 1.2.0, build fa7b24f 

使用VOLUME指令不可能告诉docker要挂载的东西。 这将严重破坏可移植性。 这条指令告诉docker这些目录中的内容不会进入映像,可以使用--volumes-from命令行参数从其他容器访问。 您必须使用-v /path/on/host:/path/in/container来运行-v /path/on/host:/path/in/container以便从主机访问目录。

在构build期间挂载主机卷是不可能的。 没有特权的build立和安装主机也会严重降低可移植性。 您可能想尝试使用wget或curl来下载构build所需的任何内容并将其放置到位。

更新:有人不会采取不作为答案,我非常喜欢它,尤其是对这个特定的问题。

好消息,现在有一种方法 –

解决scheme是摇杆: https : //github.com/grammarly/rocker

John Yani 说 : “IMO解决了Dockerfile的所有弱点,使之适合开发。”

摇臂

https://github.com/grammarly/rocker

通过引入新的命令,Rocker的目标是解决以下使用案例,这对普通的Docker来说是痛苦的:

  1. 在构build阶段挂载可重用卷,所以依赖项pipe理工具可以在构build之间使用caching。
  2. 与构build共享ssh密钥(用于拉取专用回购等),而不会将其留在生成的图像中。
  3. 在不同的图像中构build和运行应用程序,能够轻松地将工件从一个图像传递到另一个图像,理想的情况是将这个逻辑放在一个Dockerfile中。
  4. 从Dockerfiles标记/推送图像。
  5. 从shell build命令传递variables,以便它们可以replace为Dockerfile。

和更多。 这些是阻碍我们在语法上采用Docker的最关键的问题。

有一种在构build过程中安装卷的方法,但不涉及Dockerfiles。

这个技术是从任何一个你想使用的基地创build一个容器 (使用-v选项将容器安装在容器中),运行一个shell脚本来完成你的图像构build工作,然后提交容器作为图像完成后。

这样不但可以省去你不需要的多余文件(这对安全文件也是如此,比如SSH文件),它也会创build一个单一的映像。 它有缺点:commit命令不支持所有的Dockerfile指令,如果你需要编辑你的构build脚本,它不会让你停下来。

在运行容器时,主机上的目录将被创build并装载到容器中。 你可以找出这是什么目录

 $ docker inspect --format "{{ .Volumes }}" <ID> map[/export:/var/lib/docker/vfs/dir/<VOLUME ID...>] 

如果要从容器中的主机装入目录,则必须使用-v参数并指定目录。 在你的情况下,这将是:

 docker run -v /export:/export data 

所以你可以使用容器内的hosts文件夹。

我认为你可以通过一个docker命令来执行你想要做的事情,这个命令本身就是在docker容器中运行的。 请参阅Docker现在可以在Docker |中运行 Docker博客 。 像这样的技术,但实际上使用容器访问外部docker时,例如,在探索如何创build尽可能小的Docker容器| Xebia博客 。

另一篇相关的文章是优化Docker Images | CenturyLink Labs解释说,如果您在构build过程中最终下载了内容,则可以通过在一个RUN步骤中下载,构build和删除下载,避免在最终映像中浪费空间。