Dockerfile VOLUME 指令清除数据



作为更大设置的一部分,我有一个带有 Docker Compose 的多阶段 Docker 构建,它有一个builder容器,其中包含一些/var/www中的数据。当我构建名为application的第二阶段容器时,我的 Dockerfile 有这些指令

ARG APPLICATION_BUILDER
FROM $APPLICATION_BUILDER as builder
FROM busybox
COPY --from=builder --chown=www-data:www-data /var/www /var/www
VOLUME /var/www
ENTRYPOINT ["tail"]
CMD ["-f", "/dev/null"]

Dockerfilebuilder是:

FROM ubuntu:16.04
ARG APPLICATION_SOURCE_FOLDER
COPY --chown=www-data:www-data ${APPLICATION_SOURCE_FOLDER} /var/www

当我启动builder容器时,它按预期/var/www了所有数据。但是,当我使用以下命令启动application容器时:docker run -it <IMAGE>它不包含任何/var/www

如果我删除Dockerfile中的VOLUME /var/www行,则数据将按预期显示。但是我不明白为什么VOLUME指令会使数据消失,我以为这是为了将/var/www/的内容导出为卷?

除了VOLUME指令外,我是否需要在执行docker run时指定-v

VOLUME指令不会"导出目录的内容"。它说"创建一个卷并将其挂载到此路径上"。所以当你写:

COPY --from=builder --chown=www-data:www-data /var/www /var/www
VOLUME /var/www

你是说:

  • 首先,将一堆文件复制到/var/www
  • 接下来,在/var/www上装载一个空卷

卷挂载发生在构建时(影响任何后续RUN语句(和运行时(影响您在docker run中看到的环境(。

如果从Dockerfile中删除VOLUME指令,然后按如下所示运行映像:

docker run -v /var/www yourimage ...

然后 Docker 将创建一个新卷,并在挂载之前将/var/www的内容复制到其中。

同样,如果您有命名卷,则可以执行相同的操作:

docker run -v myvolume:/var/www yourimage ...

Docker 仅在您挂载的卷为空时执行此自动复制操作。如果卷具有现有内容,则只需将其装载到指定的路径上,隐藏该装入点下的任何内容。


例如。。。

我有一个名为kos的图像,其中/var/www有几个文件。我们可以通过运行ls /var/www来查看它们:

bash-5.0$ docker run kos ls /var/www
index.html
testing.jpg

如果我使用docker run -v/var/www上挂载匿名卷,我们可以看到它填充了底层/var/www目录中的内容:

bash-5.0$ docker run -v /var/www kos ls /var/www
index.html
testing.jpg

如果我们创建一个命名卷并将其挂载到/var/www上,我们会看到相同的行为:

bash-5.0$ docker volume create kos_testing
kos_testing
bash-5.0$ docker run -v kos_testing:/var/www kos ls /var/www
index.html
testing.jpg
bash-5.0$

我怀疑正在发生的事情是,当您指定 VOLUME 时,它实际上是用空卷挂载覆盖您之前复制的内容。

您不想删除该卷,因为看起来您希望保留此数据。所以你能做的,也许是切换指令。

首先声明卷,然后将数据复制到卷中。

最新更新