如何在具有共享卷的 2 个容器之间更新文件

How to update files between 2 container with shared volume

情况

假设我们有两个容器,A 和 B。

A 和 B 的共享名称卷为:shared-volumeA container 已将 shared-volume 安装到 /root/shareAB container 已将 shared-volume 安装到 /root/shareB

这意味着,当我们转到 B container 并在 /root/shareB 中创建文件 "example.txt" 时。在 A container,我们可以访问 "example.txt",使 A containerB container 通过 shared-volume.

共享卷

我正在为此使用 docker-compose:

version: '2.1'

volumes:
    shared-volume:

services:
  A:
    image: imageA
    volumes:
        - shared-volume:/root/sharedA

  B:
    image: imageB
    volumes:
        - shared-volume:/root/sharedB

问题

我正在使用 imageB 作为存储代码和资源的容器,imageA 类似于消费者、Web 服务器,它将使用 imageB 中的文件。 imageAimageB 通过命名卷共享文件(如上所示)。

根据我的测试,imageBimageA 成功共享文件。

问题是,当我用更新的文件更新 imageB 时,共享卷的文件仍然保持不变。我必须删除所有容器和卷,重新启动它,然后应用更新的文件。 这意味着我必须 运行 docker-compose down -v 然后 docker-compose up -d.

imageA 类似于网络服务器,无论出于何种原因都不应将其关闭。

我想知道我是否在某些地方有错误或遗漏了一些东西 imageA 可以在不关机的情况下从 imageB 获取更新的代码 imageA 并且它的音量?

谢谢。

Docker 认为卷是用来包含关键用户数据的,它对它们的内容一无所知。如果您依赖 Docker 的行为,它将在首次使用图像时填充命名卷,如果您更改底层容器,它不会更新卷,因为它可能会破坏用户数据.

也就是你的情况:

  1. Docker Compose 创建 shared-volume.
  2. Docker 启动 B 附加 shared-volume。由于 shared-volume 为空,因此从 imageB.
  3. 填充
  4. 您重建 imageB 并重新运行 docker-compose up
  5. Docker 启动 B 附加 shared-volume。由于 shared-volume 不为空,它保留了之前 运行.
  6. 的内容

卷不是存储代码或库的合适位置。在你所描述的完全抽象的情况下,你的代码应该内置到 imageA (这是 运行 ),当你改变它时,你应该重建两个图像。 docker-compose up --build 可以为您做到这一点。

你的问题暗示 A 容器类似于 Nginx 或 Apache Web 服务器的布局,从它的角度来看 "code and images" 只是静态的 JavaScript 并且它所服务的 PNG 文件;他们是 "data"。在该设置中,将数据卷挂载到 /var/www 上是合适的,但是生成输出的任何构建工具都需要将其显式复制到卷中。一个简单的解决方案(假设一个 JavaScript/Webpack 项目)是将项目的 dist 目录和 npm run build 绑定安装在主机上,而不是为其使用容器。

由于自动 Docker 数据复制仅在容器第一次 运行 时发生,如果将数据保存在卷中很重要,您可能需要在启动时手动复制数据。您可以使用入口点脚本执行此操作:

#!/bin/sh

# Copy application assets to the shared directory
cp -a ./assets /root/shared

# Run the CMD as the main container process
exec "$@"
# At the end of your Dockerfile
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
CMD as before