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

问题描述 投票:1回答:1

情况

比方说,我们有两个容器,A和B。

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

这意味着,当我们转到B container并在"example.txt"中创建文件/root/shareB时。在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是Web服务器之类的东西,出于任何原因都不应将其关闭。

[我想知道我是否在某些地方犯了错误或缺少某些东西,可以使imageA可以从imageB获得更新的代码而无需关闭imageA及其数量?

谢谢。

docker docker-compose docker-volume continuous-delivery
1个回答
1
投票

Docker认为卷在那里包含关键的用户数据,并且对卷的内容一无所知。如果您依赖Docker的行为,即它将在首次使用时从映像中填充命名卷,如果您更改基础容器,则它不会更新该卷,因为它可能会破坏用户数据。

也就是说,根据您的情况:

  1. Docker Compose创建shared-volume
  2. Docker启动B,并附加shared-volume。由于shared-volume为空,因此将从imageB填充。
  3. 您重建imageB,然后重新运行docker-compose up
  4. Docker启动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
© www.soinside.com 2019 - 2024. All rights reserved.