【问题标题】:Docker build/push every time - is it practical for continuous deployment?Docker build/push 每次 - 持续部署是否实用?
【发布时间】:2026-01-14 08:10:01
【问题描述】:

如果每天部署 5-10 次,每次部署时完全重建和推送一个 docker 镜像真的可行吗?

我承认 CircleCI 的 Continuous Integration and Delivery with Docker 中提到的好处,即:

请注意,Elastic Beanstalk 还允许您部署 Dockerfile 和关联的源代码而不是构建的映像,但是在 CircleCI 上预先构建映像并对其运行某种形式的验证可以让您的部署更具确定性,因为您删除构建环境作为变量在测试和生产之间有所不同。

但是,一旦包含所有依赖项和源代码,我们完全构建的 webapp 映像接近 1GB。我只是不明白部署高达 200GB/月(即每天 10 次提交,持续部署)是多么实际,而实际上 99% 的数据在构建之间没有变化。也就是说,它可能只是价值 1k 的 HTML、JS 或 CSS 被更改以添加功能。我更喜欢一种方法,其中 docker 映像包含很少更改的软件,其余的作为捆绑包的一部分被压缩。这仍然会产生一个独立的部署文件(无需下载其他依赖项),但会大大减少构建时间和带宽。

【问题讨论】:

  • 那么然后用静态(ish)的东西制作一个父dockerfile,以及一个从中派生的最终文件。主要-次要版本控制。
  • 或者您当然可以按照您描述的方式进行操作。全取决于你。或者使用带有触发拉/静态图像的 git。或者..

标签: deployment continuous-integration docker continuous-deployment dockerhub


【解决方案1】:

目前接受的方法是在机器映像中包含一个基本的 Docker 映像,该映像具有依赖项、操作系统等。将该 Docker 映像用作 Dockerfile 中的 FROM 行。这将利用 Docker 的镜像层并仅下载差异。

您可能仍希望在子 Dockerfile 中安装依赖项,因为它们会随着时间的推移而变化,但请尽量将它们中的大部分保留在基础映像中,以便下载更少。

【讨论】:

  • 在node.js这样的环境中,如何定义“依赖”?即最高 node.js 版本(0.10.32 等)或包含node_modules?我还在犹豫是否将node_modules 作为构建图像的一部分。他们比其他人更有可能改变。
  • 我确实在图像中包含了 node_modules。事实上,this somewhat pretentious blog post 让我确信 node_modules 应该签入到 repo 中。如果这样做,则不需要在 Dockerfile 中安装 npm。您的构建上下文会更大,但在构建时不需要安装。
  • 我同意在生产环境中运行 npm install 是一个坏主意,但我仍然不确定是否将 node_modules 提交到 repo。如果我有我们的 CI 服务器测试然后捆绑节点模块,那么至少我可以确定生产与测试相同,并且我的捆绑包是完全独立的,一旦到达生产服务器就不需要进一步的外部下载。另外,如果您将捆绑包存档,那么您可以随时回滚,而不必担心 npm 的可用性。