比方说,我们有两个容器,A和B。
A和B的共享名称卷为:shared-volume
。A container
已将shared-volume
安装到/root/shareA
。B container
已将shared-volume
安装到/root/shareB
。
这意味着,当我们转到B container
并在"example.txt"
中创建文件/root/shareB
时。在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
是Web服务器之类的东西,出于任何原因都不应将其关闭。
[我想知道我是否在某些地方犯了错误或缺少某些东西,可以使imageA
可以从imageB
获得更新的代码而无需关闭imageA
及其数量?
谢谢。
Docker认为卷在那里包含关键的用户数据,并且对卷的内容一无所知。如果您依赖Docker的行为,即它将在首次使用时从映像中填充命名卷,如果您更改基础容器,则它不会更新该卷,因为它可能会破坏用户数据。
也就是说,根据您的情况:
shared-volume
。B
,并附加shared-volume
。由于shared-volume
为空,因此将从imageB
填充。imageB
,然后重新运行docker-compose up
。B
,并附加shared-volume
。由于shared-volume
不为空,因此将保留上次运行时的内容。卷不是存储代码或库的适当位置。在您描述的完全抽象的情况下,您的代码应内置到imageA
中(正在运行它),并且当您对其进行更改时,应该重新构建两个映像。 docker-compose up --build
可以为您做到这一点。
[您的问题暗示了A
容器类似于Nginx或Apache Web服务器的布局,并且从其角度来看,“代码和图像”只是它所服务的静态JavaScript和PNG文件;他们是“数据”。在该设置中,将数据卷挂载到/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