如何更新docker容器映像,但按容器应用程序保留生成的文件

agi*_*git 2 docker docker-compose docker-volume

以下方案的更新容器的最佳实践是什么?

我有基于我的网络应用程序项目的图像,我正在基于更新的源代码,每月一次创建新图像.

购买我的网络应用程序生成文件或在容器中运行后及时更新一些文件.例如,app正在为每个Web用户在用户文件夹下创建新的xml文件.另一个例子是用户上传文件.

我想在运行新的更新图像后保留这些文件而不丢失.

/bin/
    /first.dll
    /second.dll
/other-soruces/
    /some.cs
    /other.cs
/user/
    /user-1.xml
    /user-2.xml
/uploads/
    /images
        /image-1.jpg
/web.config
Run Code Online (Sandbox Code Playgroud)

我应该使用Docker 的音量功能吗?还有其他策略吗?

BMi*_*tch 5

简短的回答,是的,你确实需要这些目录的卷.更具体地说,有两个卷:/ user和/ uploads.


这将成为图像和容器设计的基本实践,最好将应用程序分为三个部分:

  1. 应用程序代码,二进制文件,库和其他运行时依赖项.
  2. 应用程序访问和创建的持久数据.
  3. 修改应用程序运行方式的配置,尤其是在具有相同代码的不同环境中.

这些部件中的每一个都应该放在码头工人的不同位置.

第一部分,代码和二进制文件,在您的图像中.这是您在docker中的不同节点上运行容器以及存储在注册表中以供以后重用的内容.

第二部分是持久数据,存储在卷中.有两种主要类型的卷可供选择:命名卷和主机卷(也称为绑定挂载).命名卷具有可提高可移植性的特定功能,在首次创建卷时,它将初始化为卷位置处的图像内容.此初始化包括目录和文件权限和所有权,并可用于以初始状态为您的卷播种.主机卷(bind mount)只是从docker主机到容器的目录安装,你可以得到主机上的内容,包括文件/目录的uid/gid,以及没有初始化过程.主机卷很容易为开发人员访问,但如果你进入一个多节点swarm集群,则缺乏可移植性,并且主机映射到容器内不同用户的uid/gid会受到影响,因为容器内的用户名可能不同相同的id.您在容器内写入的未写入卷的任何文件都应视为一次性文件,并在重新创建容器以更新为新图像时丢失.您定义为卷的任何目录都应被视为该卷所拥有,并且在您更换容器时不会从映像接收更新.

最后一部分,配置,往往被忽视,但同样重要.这是在启动时注入应用程序的任何内容,告诉它在哪里连接外部数据,配置文件以改变它的行为,以及需要分离的任何内容以允许相同的映像在不同的环境中重用.这就是您使用相同图像从开发到生产的可移植性,以及如何获得公开提供的图像的可重用性.配置注入了环境变量,命令行参数,配置文件的绑定装载(当您在单个节点上运行时),以及配置+秘密,这些配置文件的绑定装载基本上与现在存储在docker的swarm中的配置文件相同.而不是在一个主机上本地.在您的情况下,/ web.config看起来很像一个配置文件,您想要移出图像并注入绑定装载或swarm配置.

要将这些组合在一起,您将需要一个定义图像的组合文件,要使用的卷以及要设置的任何配置或环境变量.