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

时间:2018-03-21 10:24:53

标签: 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

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

1 个答案:

答案 0 :(得分:5)

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

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

  1. 应用程序代码,二进制文件,库和其他运行时依赖项。
  2. 应用程序访问和创建的持久数据。
  3. 修改应用程序运行方式的配置,尤其是在具有相同代码的不同环境中。
  4. 这些部分中的每一部分应该放在码头工人的不同位置。

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

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

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

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