【问题标题】:File made in Dockerfile lost when exec docker run with "-v /path:/path" params当 exec docker 使用“-v /path:/path”参数运行时,Dockerfile 中的文件丢失
【发布时间】:2019-08-28 17:27:37
【问题描述】:

我遇到了 docker volume 问题。我想将mkdir 目录和touch 文件放在Dockerfile 中。

当我使用-v /path:/path image_name 参数执行docker run -it --name any_name 时,Dockerfile 中创建的目录和文件都丢失了。

例如:

用于构建映像 BB:tag 的 Dockerfile。

FROM AA:tag

RUN set -ex \
    && mkdir -p /var/log/my_directory/ \
    && touch /var/log/my_directory/my_file.log

CMD ["anything_cmd"]

如果我执行

docker run -it --name any_name BB:tag

my_directory 和 my_file.log 都在那里。

但如果我执行

docker run -it --name any_name -v /var/log/container_logs/any_name:/var/log/ BB:tag

my_directory 和 my_file.log 都丢失了。

docker run 时,-v 发生了什么?做这种事情的最佳做法是什么?

【问题讨论】:

  • /path 是什么/var/log/my_directory
  • @mchawre 对不清楚的命令感到抱歉。我更新了它,现在很清楚了。
  • 这类似于将一个空的 USB 驱动器安装到一个已经有文件的文件夹上,如果您列出目录中的文件,它将显示为空。目录中存在的文件只有在卸载空的 U 盘后才可用。

标签: docker dockerfile mkdir docker-volume


【解决方案1】:
  • Dockerfile 中的步骤用于创建镜像。

  • docker run 命令获取图像并创建一个容器。

  • 挂载卷(-v 参数)会将目录绑定挂载到给定位置的容器中。并且主机挂载在该卷上没有任何初始化步骤。

因此,预计只能在容器内的主机 /var/log/ 上看到来自 /var/log/container_logs/any_name 的文件。


如果您需要初始化卷,有几个选项:

  1. 您可以使用命名卷而不是主机卷。这将被初始化,但仅当该命名卷为空时。一旦命名卷中有文件,docker 将不会再次对其进行初始化,因为这可能会导致数据丢失。

  2. 您可以使用容器内的入口点脚本将文件从保存的位置复制到卷位置。图像中保存的这个位置不能被卷覆盖,否则你会遇到同样的问题。


如果您想要一个命名卷指向主机目录,您可以使用本地卷驱动程序(这是默认设置)和绑定挂载特定目录的选项。实现的各种方法包括:

  # create the volume in advance
  $ docker volume create --driver local \
      --opt type=none \
      --opt device=/home/user/test \
      --opt o=bind \
      test_vol

  # create on the fly with --mount
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
    foo

  # inside a docker-compose file
  ...
  volumes:
    bind-test:
      driver: local
      driver_opts:
        type: none
        o: bind
        device: /home/user/test
  ...

如果您想使用入口点脚本,请参阅my base image repo 中的卷缓存说明。

【讨论】:

  • 感谢帮助我了解音量。但是当我尝试时仍然有些麻烦。我想创建几个容器(例如container_acontainer_bcontainer_c)都基于图像BB:tag,每个容器都有自己的/var/log。而在主机/var/log/container_logs/目录下,可以看到container_acontainer bcontainer_c。现在我可以创建/var/log/container_logs/ 作为卷,但是我何时何地编写代码来创建目录container_acontainer_bcontainer_c
  • 我通过添加 docker-entrypoint.sh 文件来解决它。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多