根据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
文件。
我在做什么错了?
答案 0 :(得分:2)
有几种类型的卷:
主机卷,该卷将主机上的目录装载到容器中。 Docker从不初始化这些。无论主机的状态如何,都将成为该目录中的目录内容。这是您创建的卷的类型。当容器uid / gid与您的主机用户不匹配时,它们具有uid / gid权限问题的缺点。
匿名卷,这是带有长名称向导的已命名卷。没有关于匿名卷的目标是什么的信息,尤其是在删除容器时,因此,您至少要给卷起一个名字。如果使用VOLUME
定义卷,然后在运行容器时忘记定义卷,则这些为默认设置。
命名卷,通过为其指定有效名称而不是路径作为源来创建。对于大多数情况,建议使用这些选项,除非您需要使用主机卷从外部访问数据。命名卷的优点是,泊坞窗在创建时将其初始化为该位置的映像内容。这种初始化仅在首次创建该卷时发生,因此,除非有类似入口点的数据将其他目录中的数据复制回该卷中,否则不会反映对映像的更改。
如果要查看已初始化数据的命名卷,则如下所示:
$ docker run --volume testvol:/myvol 159b3387c7eb
创建一个名为testvol
的卷。
答案 1 :(得分:1)
当您声明一个VOLUME
并没有在卷中预先填充任何内容时,它仅描述了预期的安装点。
当您使用--volume
参数调用Docker时,它将使用您的本地目录替换该目标目录中的所有内容,从而将该本地目录有效地安装在目标位置的顶部。该原始位置上的任何东西都会被坐骑遮挡并且无法访问。
如果您需要在卷中预先填充内容,请在安装卷之前执行此操作,或者使用ENTRYPOINT
脚本在容器启动时初始化该目录。