当前位置: 首页 > 知识库问答 >
问题:

如何在生成期间将主机卷装入Dockerfile中的docker容器

令狐献
2023-03-14

原题:如何使用DockerFile中的卷指令?

我要解决的实际问题是--如何在构建期间将主机卷装入Dockerfile中的docker容器中,即在docker build期间具有docker run-v/export:/export功能

对我来说,其背后的原因是在Docker中构建东西时,我不希望那些(apt-get install)缓存锁定在单个Docker中,而是共享/重用它们。这就是我问这个问题的主要原因。

最新更新:

在docker V18.09之前,正确答案应该是以以下开头的答案:

有一种方法可以在构建期间装入卷,但它不涉及DockerFiles。

Dockerize apt-cacher-ng服务
https://docs.docker.com/engine/examples/apt-cacher-ng/

这是码头工人对这个/我的问题的解决方案,不是直接的,而是间接的。这是docker建议我们做的正统方法。我承认这比我想问的好。

另一种方法是,新接受的答案,例如V18.09中的Buildkit。

随便挑一个适合你的。

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

它说Data volumes特性“从Docker Remote 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"]
$ 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

共有1个答案

洪涵亮
2023-03-14

首先,回答“为什么不管用?”在Dockerfile中定义时,只能定义目标,而不能定义卷的源。在构建过程中,您将只能从中获取一个匿名卷。该匿名卷将在每个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"]

这将导致构建只包含得到的二进制文件,而不包含完整的/导出目录。

Buildkit将于18.09年从experimental中推出。这是对构建过程的完全重新设计,包括更改前端解析器的能力。其中一个解析器更改实现了run--mount选项,该选项允许您为run命令装入一个缓存目录。例如。下面是一个挂载一些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

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启用buildkit。

如果出现不支持mount标志的错误,则表明您没有使用上述变量启用buildkit,或者没有使用位于Dockerfile顶部的语法行启用实验语法,该语法行位于其他行(包括注释)之前。请注意,切换buildkit的变量只有在docker安装内置buildkit支持时才会起作用,这需要客户端和服务器上的docker版本18.09或更新版本。

 类似资料:
  • 问题内容: 原始问题:如何在Dockerfile中使用VOLUME指令? 我要解决的实际问题是-如何在构建期间将主机卷挂载到Dockerfile中的Docker容器中,即在期间具有该功能。 对我而言,其背后的原因是在Docker中构建东西时,我不希望将()缓存锁定在单个Docker中,而是共享/重用它们。这就是我问这个问题的主要原因。 最近更新: 在docker v18.09之前,正确的答案应该是

  • 这是我当前的DockerFile: 我的项目是这样的:

  • 问题内容: 我对Docker中的整个数据量过程有疑问。基本上,这里有两个Dockerfile及其各自的运行命令: Dockerfile 1- 命令1- Dockerfile 2- 命令2- 因此,奇怪的是第一个dockerfile和命令按预期工作。docker守护程序将目录从容器装载到主机的位置。因此,我可以根据需要编辑配置文件,它们将在重新启动后保留在容器中。 但是,对于第二个dockerfil

  • 问题内容: 我已经能够成功使用以下卷在Docker容器之间共享文件夹 但是我的问题是,这与在Dockerfile中使用命令之间有什么区别 我正在使用带有命令的图像,并且想知道如何与主机共享它。我已经使用上面的命令完成了此操作,但我不知道是否同时需要和和。 问题答案: 该命令将在您的容器中安装一个目录,并将在该目录中创建或编辑的所有文件存储 在容器文件结构外部的 主机磁盘上,绕过联合文件系统。 这个