比方说,我们有两个容器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
时,共享volumne的文件仍然保持不变。我必须删除所有容器和卷,重新启动它,然后应用更新的文件。
这意味着我必须先运行docker-compose down -v
然后运行docker-compose up -d
。
imageA
是Web服务器之类的东西,不应出于任何原因将其关闭。
我想知道我是否在某些地方犯了错误或缺少某些东西,可以使imageA
可以从imageB
获得较新的代码而无需关闭imageA
并且数量如此?
谢谢。
答案 0 :(得分:1)
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