Docker,更新图像还是只使用绑定挂载来获取网站代码?

Docker,更新图像还是只使用绑定挂载来获取网站代码?,docker,docker-compose,Docker,Docker Compose,我正在使用Django,但我想这个问题适用于任何web项目 在我们的例子中,有两种类型的代码,第一种是python代码(在django中运行),另一种是静态文件(html/js/css) 我可以在任何代码发生更改时发布新图像。 或者我可以使用bind mounts作为代码。(对于django,我们可以绑定挂载项目根目录和静态目录) 如果我对代码使用bind mounts,我可以在代码更改时更新生产机器(可能使用git pull) 然后,docker image将处理严格来说不是我们自己的代码更改

我正在使用Django,但我想这个问题适用于任何web项目

在我们的例子中,有两种类型的代码,第一种是python代码(在django中运行),另一种是静态文件(html/js/css)

我可以在任何代码发生更改时发布新图像。
或者我可以使用
bind mounts
作为代码。(对于django,我们可以绑定挂载项目根目录和静态目录)

如果我对代码使用
bind mounts
,我可以在代码更改时更新生产机器(可能使用
git pull

然后,docker image将处理严格来说不是我们自己的代码更改的更新。(如库更新或新设置,如设置elasticsearch)


这种方法是否意味着任何明显的缺点

出于安全原因,建议操作系统更新最新的安全补丁,但docker映像将以不变的方式发布,以便我们始终能够在生产之外重现生产问题,因此操作系统不会因发布的安全补丁而更新自身。因此,这意味着我们需要经常重建和部署docker映像,以确保安全

因此,我更愿意使用我的代码和静态文件发布一个新的docker映像,因为它们肯定会更频繁地更改,因此需要频繁发布,这意味着您可以在安全补丁方面使操作系统更为最新,而无需在生产中重建docker映像,以使操作系统保持最新


注意,我假设您至少每周发布一次新代码或静态文件,否则,我仍然建议至少每周更新一次docker映像,以便获得所有正在使用的软件的最后一个安全补丁。

通常,我所看到的针对此问题的更面向docker的解决方案会学习如何在docker映像中打包整个应用程序。这尤其包括应用程序代码

我建议这样做有三个很好的理由:

  • 如果您有一个可复制的路径来创建一个自包含的映像,任何人都可以创建并复制它。这包括您的开发人员,他们可以在生产系统实际投入生产之前测试其几乎完全相同的副本。如果是Docker图像,再加上这个地方的代码,再加上其他地方的静态文件,就很难确定你有一个与生产相匹配的完美设置

  • 一些更先进的面向Docker的工具(Kubernetes、Amazon ECS、Docker Swarm、Hashicorp Nomad等)使得将容器和图像作为一级对象处理变得相当简单,但说“这个图像加上这个附加文件的glop”更为棘手

  • 如果您使用服务器自动化工具(Ansible、Salt Stack、Chef等)来推出代码,那么也可以直接使用这些工具推出正确的运行时环境。使用Docker仅仅打包运行时环境并不会给您带来更多的复杂性和一些安全风险。(您可以将Packer或Vagrant与此工具集一起使用,以模拟VM中的部署序列,以便进行预生产测试。)

  • 您还将在许多SO问题中看到一个序列,Dockerfile将应用程序代码复制到某个目录,然后,
    docker compose.yml
    bind将当前主机目录装载到同一目录上。在这个设置中,容器环境反映了开发人员的桌面环境,并不真正测试Docker映像中内置的内容

    (“静态文件”在“是应用程序还是数据?”之间的灰色区域结束在这个问题的上下文中,我倾向于将它们打包到映像中,特别是如果它们来自您的正常构建过程。这尤其包括您正在运行的应用程序的主UI。如果像大型映像或视频资产这样的东西您可以合理地托管在完全独立的服务器上,那么它可能会使您更加安全(请分开供应。)