"a bind mount won't copy the container contents to the host automatically, unlike a named volume"

"a bind mount won't copy the container contents to the host automatically, unlike a named volume"

需要澄清评论 here

The only 'problem' with a bind mount is that it won't copy the container contents to the host automatically, unlike a named volume. docs.docker.com/compose/compose-file/#volumes

这准确吗?如果是,那么:

  1. 如何在使用 bind mount 时将容器的“新数据”(例如不断增长的数据库)导入主机(以在容器重启时保留数据)?
  2. named volumes 之前,Docker 如何在容器重新启动时持久保存数据?

The only 'problem' with a bind mount is that it won't copy the container contents to the host automatically, unlike a named volume.

这准确吗?

接近准确,但我可以看到混乱。主机卷,又名绑定安装,没有 docker 的初始化功能。对于匿名和命名卷,docker 将使用该路径中的图像内容初始化卷。此初始化包括有助于避免权限错误的所有权和权限。当创建容器并且卷是新的或空的时,此初始化仅 运行s,因此后续容器不会拾取对较新映像版本中所做的映像的更改。

If yes, then:

  1. how does one get the container's "new data" (e.g. a growing database) into the host when using a bind mount (to persist the data in case of a container restart)?

从容器中的应用程序读取和写入将按预期继续到绑定装载中使用的主机文件系统。只是初始化步骤没有运行.

  1. how did Docker persist data across container restarts before there were named volumes?

有数据容器,从其他容器挂载卷,但这是不灵活的(所有卷路径都固定到数据容器中的路径)和持久数据与临时容器的混合管理,因此已被淘汰.

卷用于处理容器之间的数据持久化。单个容器重新启动(而不是被替换)仍然会有所有容器特定的文件系统更改。 docker rm 命令删除这些文件系统更改,以及容器日志和容器的 metadata/configuration。

容器特定的更改是 read/write 覆盖文件系统的顶层 docker。卷挂载都是单独挂载到这个覆盖文件系统的子目录中(就像 /home/var 通常是 Linux 主机的 / 文件系统中的单独文件系统挂载,所有读取并写入那些其他路径去一个单独的底层文件系统)。

如果您要将卷装载到容器中,并且希望该卷可靠地包含映像中的某些内容,则需要在容器启动时手动将其复制到那里。一种方法是使用入口点包装器脚本:

#!/bin/sh
# Copy data into a possibly-mounted location
cp -a /app/static /var/www
# Then run the image's CMD
exec "$@"

您可以将其包含在图像的 Docker 文件中

# Must use JSON-array syntax
ENTRYPOINT ["/app/entrypoint.sh"]
CMD same as it was before

这里有两个关于 Docker 命名卷的初始化行为的重要细节需要注意。首先,您注意到,Docker 仅将内容复制到 Docker 命名卷的卷中;它不会发生在绑定挂载上,也不会发生在 Kubernetes 等其他环境中。

第二个更微妙的细节是初始化仅在容器第一次运行时发生。如果您装载到容器中的卷中已经有内容,它将隐藏已经存在的内容。在其他 SO 问题中,您可以看到此清单,例如,“我将一个包添加到我的节点 package.json 文件中,但是当我将 node_modules 目录放入卷中时,它会忽略更新”或“我正在使用卷将内容导出到 nginx 代理,但它没有更新”。

我认为@BMitch 接受的答案是正确的,但我会尝试添加一些细节,希望对您有用。

Is this accurate? If yes, then:

考虑到我的声明正在接受审查 - 我在这里完全服从@BMitch :)! 不过我还要补充:

how does one get the container's "new data" (e.g. a growing database) into the host when using a bind mount (to persist the data in case of a container restart)?

主机卷命名卷都可以做到这一点。

我认为争论的焦点是你想发生什么:

  • 容器的第一个运行
  • 容器运行的后续
  • 主机系统上卷的location/accessibility。

一旦将一个卷附加到一个容器(无论是命名卷还是绑定安装),存储到该卷的任何内容都应该在重启之间保留 - 这实际上是免费的。这假定相同的 docker-compose 配置,并且没有手动删除卷。

以前使用 命名卷 有点限制,因为您无法追踪日志,也无法直接从主机 轻松编辑代码 就像你可以使用 绑定挂载 - 但似乎问题已解决/现在有解决办法。

绑定装载能够在重启之间保留数据。我个人发现绑定卷在 99% 的时间里都能满足我的要求,也就是说,命名卷现在可以 'do it all' 并且我会继续使用它们。

尽管它们之间存在差异,但我敢肯定它们偶尔还是会咬人,要求他们联系 实际 专家,而不是像我这样的用户: ).