【问题标题】:How to update files between 2 container with shared volume如何在具有共享卷的 2 个容器之间更新文件
【发布时间】:2019-11-14 10:32:24
【问题描述】:

情况

假设我们有两个容器,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 可以在不关闭 imageA 的情况下从 imageB 获取更新的代码,而且它的音量很大?

谢谢。

【问题讨论】:

    标签: docker docker-compose docker-volume continuous-delivery


    【解决方案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
    

    【讨论】:

    • 谢谢,我认为这是我目前唯一的解决方案。我想知道在不影响运行应用程序的情况下,对于 CD 资源是否还有其他最佳做法?
    猜你喜欢
    • 1970-01-01
    • 2021-10-10
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2019-12-26
    相关资源
    最近更新 更多