原始问题:如何在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,但是现在摇杆已经停产了,我再次将答案恢复为 “不可能” 。
旧更新:
答案是“不可能”。我可以接受它作为答案,因为我知道这个问题已经在https://github.com/docker/docker/issues/3156上进行了广泛讨论。我可以理解,对于Docker开发人员而言,可移植性是至关重要的问题。但是作为docker用户,我不得不说我对该功能的缺失感到非常失望。让我在前面的讨论中引用一句话来结束我的论点:“
我想使用Gentoo作为基本映像,但绝对不希望在映像建立后将 >
1GB的Portage树数据放在任何层中。您如果不是因为巨大的可移植树不必在安装过程中出现在映像中,则可能会有一些紧凑的容器。“是的,我可以使用wget或curl来下载所需的文件,但事实是,仅出于可移植性考虑,现在每次我构建Gentoo基本映像时,我都必须下载>
1GB的Portage树,这既不高效也不友好。另外,软件包存储库将始终位于/ usr /
portage下,因此始终位于Gentoo下。再次,我尊重这一决定,但同时也请允许我对我表示失望。
*详细的 *原始问题 :
从
通过卷共享目录
http://docker.readthedocs.org/en/v0.7.3/use/working_with_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"]
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
?” 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或更高版本的安装,并使用启用buildkit
export DOCKER_BUILDKIT=1
。
如果遇到不支持mount标志的错误,则表明您没有使用上述变量启用buildkit,或者您没有在Dockerfile顶部的语法行中启用实验性语法其他任何行,包括评论。请注意,仅当您的docker安装具有内置的buildkit支持时,切换buildkit的变量才起作用,该客户端和服务器上的Docker需要版本18.09或更高版本。
问题内容: 我对Docker中的整个数据量过程有疑问。基本上,这里有两个Dockerfile及其各自的运行命令: Dockerfile 1- 命令1- Dockerfile 2- 命令2- 因此,奇怪的是第一个dockerfile和命令按预期工作。docker守护程序将目录从容器装载到主机的位置。因此,我可以根据需要编辑配置文件,它们将在重新启动后保留在容器中。 但是,对于第二个dockerfil
原题:如何使用DockerFile中的卷指令? 我要解决的实际问题是--如何在构建期间将主机卷装入Dockerfile中的docker容器中,即在期间具有功能。 对我来说,其背后的原因是在Docker中构建东西时,我不希望那些()缓存锁定在单个Docker中,而是共享/重用它们。这就是我问这个问题的主要原因。 最新更新: 在docker V18.09之前,正确答案应该是以以下开头的答案: 有一种方
问题内容: 在Docker容器中挂载主机目录非常容易。 但是我需要另一种方式。 我使用Docker容器作为开发环境来开发WordPress插件。该Docker容器包含运行WordPress所需的一切(MySQL,Apache,PHP和WordPress)。我从Docker容器中的主机挂载了我的插件src文件夹,以便可以在开发期间测试我的插件。 对于调试,如果我在主机上运行的IDE具有对Docker
假设我有一个应用程序具有这个简单的DockerFile: 然后我运行了一个容器: 所以它工作正常,并将一些日志存储在docker容器的中。 我也看到docker-mount目录从容器到主机,但它并没有解决我的问题我需要一种方法备份我的文件从Docker到主机。
问题内容: 我有一个正在进行dockerizing的开发环境,并且我希望能够实时重新加载所做的更改而不必重建docker映像。我使用docker compose是因为redis是我应用程序的依赖项之一,我喜欢能够链接redis容器 我在我的中定义了两个容器: 我已经到了我应用程序的dockerfile中添加卷的地步,但是如何将主机的目录挂载到卷中,以便对代码的所有实时编辑都可以反映在容器中? 这是
我想挂载我的usb驱动器到一个正在运行的docker实例,手动备份一些文件。 我知道的特性,但这会创建一个新的容器。注意:它是一个nextcloudpi容器。