Docker VOLUME指令未使用现有数据初始化卷

时间:2019-11-12 20:42:41

标签: docker dockerfile

根据Docker documentation关于VOLUME的说明:

  

docker run命令使用基本映像内指定位置上存在的任何数据初始化新创建的卷。例如,考虑以下Dockerfile片段:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
     

此Dockerfile生成一个映像,该映像使docker run在/ myvol处创建一个新的挂载点并将问候文件复制到新创建的卷中。

我无法使用此确切的Dockerfile并运行以下命令来复制此行为:

$ docker run --volume ~/testdir:/myvol 159b3387c7eb

创建的testdir目录不包含预期的greeting文件。

我在做什么错了?

2 个答案:

答案 0 :(得分:2)

有几种类型的卷:

  1. 主机卷,该卷将主机上的目录装载到容器中。 Docker从不初始化这些。无论主机的状态如何,都将成为该目录中的目录内容。这是您创建的卷的类型。当容器uid / gid与您的主机用户不匹配时,它们具有uid / gid权限问题的缺点。

  2. 匿名卷,这是带有长名称向导的已命名卷。没有关于匿名卷的目标是什么的信息,尤其是在删除容器时,因此,您至少要给卷起一个名字。如果使用VOLUME定义卷,然后在运行容器时忘记定义卷,则这些为默认设置。

  3. 命名卷,通过为其指定有效名称而不是路径作为源来创建。对于大多数情况,建议使用这些选项,除非您需要使用主机卷从外部访问数据。命名卷的优点是,泊坞窗在创建时将其初始化为该位置的映像内容。这种初始化仅在首次创建该卷时发生,因此,除非有类似入口点的数据将其他目录中的数据复制回该卷中,否则不会反映对映像的更改。

如果要查看已初始化数据的命名卷,则如下所示:

$ docker run --volume testvol:/myvol 159b3387c7eb

创建一个名为testvol的卷。

答案 1 :(得分:1)

当您声明一个VOLUME并没有在卷中预先填充任何内容时,它仅描述了预期的安装点。

当您使用--volume参数调用Docker时,它将使用您的本地目录替换该目标目录中的所有内容,从而将该本地目录有效地安装在目标位置的顶部。该原始位置上的任何东西都会被坐骑遮挡并且无法访问。

如果您需要在卷中预先填充内容,请在安装卷之前执行此操作,或者使用ENTRYPOINT脚本在容器启动时初始化该目录。