如何在具有共享卷的 2 个容器之间更新文件
How to update files between 2 container with shared volume
情况
假设我们有两个容器,A 和 B。
A 和 B 的共享名称卷为:shared-volume
。
A container
已将 shared-volume
安装到 /root/shareA
。
B container
已将 shared-volume
安装到 /root/shareB
。
这意味着,当我们转到 B container
并在 /root/shareB
中创建文件 "example.txt"
时。在 A container
,我们可以访问 "example.txt"
,使 A container
和 B 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
中的文件。 imageA
和 imageB
通过命名卷共享文件(如上所示)。
根据我的测试,imageB
与 imageA
成功共享文件。
问题是,当我用更新的文件更新 imageB
时,共享卷的文件仍然保持不变。我必须删除所有容器和卷,重新启动它,然后应用更新的文件。
这意味着我必须 运行 docker-compose down -v
然后 docker-compose up -d
.
imageA
类似于网络服务器,无论出于何种原因都不应将其关闭。
我想知道我是否在某些地方有错误或遗漏了一些东西 imageA
可以在不关机的情况下从 imageB
获取更新的代码 imageA
并且它的音量?
谢谢。
Docker 认为卷是用来包含关键用户数据的,它对它们的内容一无所知。如果您依赖 Docker 的行为,它将在首次使用图像时填充命名卷,如果您更改底层容器,它不会更新卷,因为它可能会破坏用户数据.
也就是你的情况:
- Docker Compose 创建
shared-volume
.
- Docker 启动
B
附加 shared-volume
。由于 shared-volume
为空,因此从 imageB
. 填充
- 您重建
imageB
并重新运行 docker-compose up
。
- Docker 启动
B
附加 shared-volume
。由于 shared-volume
不为空,它保留了之前 运行. 的内容
卷不是存储代码或库的合适位置。在你所描述的完全抽象的情况下,你的代码应该内置到 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
情况
假设我们有两个容器,A 和 B。
A 和 B 的共享名称卷为:shared-volume
。
A container
已将 shared-volume
安装到 /root/shareA
。
B container
已将 shared-volume
安装到 /root/shareB
。
这意味着,当我们转到 B container
并在 /root/shareB
中创建文件 "example.txt"
时。在 A container
,我们可以访问 "example.txt"
,使 A container
和 B 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
中的文件。 imageA
和 imageB
通过命名卷共享文件(如上所示)。
根据我的测试,imageB
与 imageA
成功共享文件。
问题是,当我用更新的文件更新 imageB
时,共享卷的文件仍然保持不变。我必须删除所有容器和卷,重新启动它,然后应用更新的文件。
这意味着我必须 运行 docker-compose down -v
然后 docker-compose up -d
.
imageA
类似于网络服务器,无论出于何种原因都不应将其关闭。
我想知道我是否在某些地方有错误或遗漏了一些东西 imageA
可以在不关机的情况下从 imageB
获取更新的代码 imageA
并且它的音量?
谢谢。
Docker 认为卷是用来包含关键用户数据的,它对它们的内容一无所知。如果您依赖 Docker 的行为,它将在首次使用图像时填充命名卷,如果您更改底层容器,它不会更新卷,因为它可能会破坏用户数据.
也就是你的情况:
- Docker Compose 创建
shared-volume
. - Docker 启动
B
附加shared-volume
。由于shared-volume
为空,因此从imageB
. 填充
- 您重建
imageB
并重新运行docker-compose up
。 - Docker 启动
B
附加shared-volume
。由于shared-volume
不为空,它保留了之前 运行. 的内容
卷不是存储代码或库的合适位置。在你所描述的完全抽象的情况下,你的代码应该内置到 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