为了账号安全,请及时绑定邮箱和手机立即绑定

如何在构建期间将主机卷挂载到Dockerfile中的Docker容器中

如何在构建期间将主机卷挂载到Dockerfile中的Docker容器中

大话西游666 2019-10-06 11:13:01
原始问题:如何在Dockerfile中使用VOLUME指令?我要解决的实际问题是-如何在构建期间将主机卷挂载到Dockerfile中的Docker容器中,即在期间具有该docker run -v /export:/export功能docker build。对我而言,其背后的原因是在Docker中构建东西时,我不希望将(apt-get install)缓存锁定在单个Docker中,而是共享/重用它们。这就是我问这个问题的主要原因。最新更新:在docker v18.09之前,正确的答案应该是以下开头:有一种在构建期间挂载卷的方法,但是它不涉及Dockerfiles。但是,这是一个措辞不佳,组织有序且没有得到支持的答案。当我重新安装docker contains时,我偶然发现了以下文章:Dockerize apt-cacher-ng服务https://docs.docker.com/engine/examples/apt-cacher-ng/那是码头工人对这个/我的问题的解决方案,不是直接而是间接的。这是docker建议我们这样做的正统方式。我承认这比我在这里要问的要好。另一种方法是新接受的答案,例如v18.09中的Buildkit。选择最适合您的。是:曾经有一个解决方案-摇杆,它不是来自Docker,但是现在摇杆已经停产了,我再次将答案恢复为“不可能”。
查看完整描述

3 回答

?
慕雪6442864

TA贡献1812条经验 获得超5个赞

首先,回答“为什么不起作用VOLUME?” VOLUME在Dockerfile中定义a 时,只能定义目标,而不能定义卷的源。在构建期间,您将仅从中获得一个匿名卷。该匿名卷将在每个RUN命令处挂载,并预先填充映像的内容,然后在RUN命令末尾丢弃。仅保存对容器所做的更改,不保存对体积的更改。


自从提出此问题以来,已经发布了一些功能可能会有所帮助。首先是多阶段构建,它允许您构建磁盘空间效率低下的第一阶段,并将所需的输出仅复制到出厂的最后阶段。第二个功能是Buildkit,它极大地改变了图像的构建方式,并向构建中添加了新功能。


对于多阶段构建,您将有多FROM行,每行开始创建一个单独的映像。默认情况下,仅最后一张图像被标记,但是您可以复制前一阶段的文件。标准用途是具有一个编译器环境来构建一个二进制或其他应用程序工件,以及一个运行时环境作为在该工件上进行复制的第二阶段。你可以有:


FROM debian:sid as builder

COPY export /export

RUN compile command here >/result.bin


FROM debian:sid

COPY --from=builder /result.bin /result.bin

CMD ["/result.bin"]

这将导致构建仅包含生成的二进制文件,而不包含完整的/ export目录。


Buildkit将于18.09发布。这是对构建过程的完全重新设计,包括更改前端解析器的功能。这些解析器更改之一已实现了该RUN --mount选项,该选项使您可以为运行命令安装缓存目录。例如,这是一个挂载一些debian目录的文件(通过重新配置debian映像,这可以加快软件包的重新安装速度):


# syntax = docker/dockerfile:experimental

FROM debian:latest

RUN --mount=target=/var/lib/apt/lists,type=cache \

    --mount=target=/var/cache/apt,type=cache \

    apt-get update \

 && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \

      git

您可以根据自己的应用程序缓存来调整缓存目录,例如$ HOME / .m2(用于maven)或/root/.cache(用于golang)。


TL; DR:答案在这里:使用该RUN --mount语法,您还可以从构建上下文绑定安装只读目录。该文件夹必须存在于构建上下文中,并且不会映射回主机或构建客户端:


# syntax = docker/dockerfile:experimental

FROM debian:latest

RUN --mount=target=/export,type=bind,source=export \

    process export directory here...

请注意,由于目录是从上下文挂载的,因此它也是只读挂载的,您不能将更改推回主机或客户端。构建时,您需要18.09或更高版本的安装,并使用启用构建工具包export DOCKER_BUILDKIT=1。


查看完整回答
反对 回复 2019-10-06
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

无法使用该VOLUME指令告诉docker 挂载什么。那会严重破坏便携性。该指令告诉docker这些目录中的内容不会出现在图像中,并且可以使用--volumes-from命令行参数从其他容器中进行访问。您必须使用容器来-v /path/on/host:/path/in/container从主机访问目录。

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


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 3505 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信