在 linux 主机上装载种子卷

Mount seeded volume on linux host

我想创建一个数据库映像并在其中植入一些初始数据。这似乎工作正常,因为我能够创建一个容器,其卷由 docker 管理。但是,当我尝试将卷挂载到我的 linux 主机上的目录时,它被创建为 empty 而不是 seeded

在尝试不同配置几个小时后,我将问题缩小到核心:与主机上的卷关联的容器中的文件夹内容在创建时被覆盖。

下面是创建包含单个文件的文件夹的简单 Dockerfile。当容器启动时,它会打印出已安装文件夹的内容。

FROM ubuntu:18.04

RUN mkdir /opt/test
RUN touch /opt/test/myFile.txt

VOLUME /opt/test

CMD ["ls", "/opt/test"]

我正在构建图像:docker build -t test .

docker

管理的卷
$ docker run -v volume-test:/opt/test --name test test
myFile.txt

这里我得到了预期的输出。卷安装在 docker 管理的 space 中。所以 docker volume inspect volume-test 的输出是:

{
  "CreatedAt": "2020-05-13T10:09:29+02:00",
  "Driver": "local",
  "Labels": null,
  "Mountpoint": "/var/snap/docker/common/var-lib-docker/volumes/volume-test/_data",
  "Name": "volume-test",
  "Options": null,
  "Scope": "local"
}

安装在主机上的卷

$ docker run -v $(pwd)/volume:/opt/test --name test test

由于文件夹为空,因此没有返回任何内容...但是,即使我正在执行 docker 运行命令作为另一个用户。

drwxr-xr-x 2 root    root    4096 May 13 10:11 volume

作为最后的测试,我试图查看当我预先为卷创建文件夹并向其中添加一些内容时会发生什么(在我的例子中是一个名为 anotherFile.txt 的文件)。 当我现在 运行ning 容器时,我得到以下结果:

$ docker run -v $(pwd)/volume:/opt/test --name test test
anotherFile.txt

这让我得出结论,容器文件夹中的内容被主机上文件夹的内容覆盖。

我也可以用 docker inspect -f '{{ .Mounts }}' test 验证该卷是否安装在正确的位置:

[{bind  /pathWhere/pwd/pointedTo/volume /opt/test   true rprivate}]

现在我的问题:有没有办法让主机上的卷具有与 docker 管理的卷相同的行为,其中的内容容器中的 /opt/test 文件夹被复制到主机上定义为 volume?

的文件夹中

旁注:在 windows 上使用 docker 并启用选项 Shared Folders 时似乎就是这种情况...

此外,这里似乎已经有人问过 similar question 但没有找到答案。我决定单独制作一个 post,因为我认为这是描述此问题的最通用示例。

期望的情况

docker 图像中的数据放置在主机上的指定路径中。

你现在的情况

  1. 创建镜像时,数据放入/opt/test
  2. 启动容器时,将卷挂载到 /opt/test

问题

因为您装载的路径与放置数据的路径相同,所以您的数据会被覆盖。

解决方案

  1. 在 docker-build 期间在映像中创建一个文件,例如 touch /opt/test/data/myFile.txt
  2. 使用不同的路径来装载您的卷,这样数据就不会被覆盖,例如 /opt/test/mount
  3. 使用'CMD'将文件复制到卷,像这样:CMD ["cp", "-n" "/opt/test/data/*", "/opt/test/mount /"]

咨询来源