【发布时间】:2014-11-20 22:53:13
【问题描述】:
自从 2014 年提出这个问题以来,发生了许多情况,许多事情发生了变化。我今天再次重新讨论这个话题,我正在第 12 次编辑这个问题以反映最新的变化。这个问题可能看起来很长,但它是按时间倒序排列的,所以最新的变化在顶部,随时停止阅读。
我想解决的问题是——如何在构建期间将主机卷挂载到 Dockerfile 中的 docker 容器中,即在docker build 期间具有docker run -v /export:/export 功能。
对我来说,背后的一个原因是在 Docker 中构建东西时,我不希望那些 (apt-get install) 缓存锁定在单个 Docker 中,而是共享/重用它们。
这是我问这个问题的主要原因。我今天面临的另一个原因是试图利用来自主机的巨大私人回购,否则我必须使用我的私人 ssh 密钥从 docker 内的私人回购中执行git clone,我不知道如何和还没看。
最新更新:
@BMitch 回答中的 Buildkit
使用
RUN --mount语法,您还可以从构建上下文绑定挂载只读目录...
它现在已经内置在 docker 中(我认为它是一个第三方工具),只要你的超过 18.09。我的现在是 20.10.7 -- https://docs.docker.com/develop/develop-images/build_enhancements/
启用 BuildKit 构建
全新安装 docker 最简单的方法是在调用 docker build 命令时设置 DOCKER_BUILDKIT=1 环境变量,例如:
$ DOCKER_BUILDKIT=1 docker build .
否则,你会得到:
the --mount option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled
因此,如上所述,这将是我的第二个用例的完美解决方案。
2019 年 5 月 7 日更新:
在docker v18.09之前,正确答案应该是以下开头的那个:
有一种方法可以在构建期间挂载卷,但不涉及 Dockerfile。
但是,这是一个表述不佳、组织有序且支持不充分的答案。当我重新安装我的 docker contains 时,我偶然发现了以下文章:
Docker 化一个 apt-cacher-ng 服务
https://docs.docker.com/engine/examples/apt-cacher-ng/
这是码头工人对这个/我的问题的解决方案,不是直接而是间接。这是 docker 建议我们做的正统方式。而且我承认这比我在这里要问的要好。
另一种方法是,新接受的答案,例如 v18.09 中的 Buildkit。
选择适合你的。
曾经:曾经有一个解决方案——rocker,它不是来自 Docker,但现在该 rocker 已停产,我将答案回复为 “不可能” 再次。
旧更新:所以答案是“不可能”。我可以接受它作为答案,因为我知道该问题已在 https://github.com/docker/docker/issues/3156 上进行了广泛讨论。我可以理解,可移植性对于 docker 开发人员来说是一个最重要的问题;但作为 docker 用户,我不得不说我对这个缺失的功能感到非常失望。让我引用上述讨论中的一句话来结束我的论点:“我想使用 Gentoo 作为基础镜像,但绝对不希望在镜像生成后的任何层中有 > 1GB 的 Portage 树数据。构建。如果不是在安装过程中必须出现在映像中的巨大 portage 树,您可以拥有一些不错的紧凑容器。“是的,我可以使用 wget 或 curl 下载我需要的任何内容,但是仅出于可移植性考虑,现在我每次构建 Gentoo 基础映像时都必须下载超过 1GB 的 Portage 树,这既不高效也不友好。此外,软件包存储库总是在 /usr/portage 下,因此在 Gentoo 下总是可移植的。再次,我尊重这个决定,但同时请允许我表达我的失望。谢谢。
原问题详细说明:
来自
通过卷共享目录
http://docker.readthedocs.org/en/v0.7.3/use/working_with_volumes/
它说数据卷功能“从 Docker 远程 API 版本 1 开始可用”。我的 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
【问题讨论】:
-
显然更当前的功能请求(不是我希望它实现,但以防万一):docker/docker #14080
-
确实有一个广泛的讨论,即不应允许在构建期间链接主机目录和容器目录,例如
VOLUME ~/host_dir ~/container_dir。讨论相当广泛,有没有简单的方法来总结原因是什么? -
很遗憾,链接docker.readthedocs.org/en/v0.7.3/use/working_with_volumes 已损坏。不过,感谢彻底的问答。
-
感谢@ramhiser 的通知,docker.readthedocs.org/en/v0.7.3/use/working_with_volumes 的下划线链接现已更新,可点击。