将dockerized node.js运送到生产时, 运送包含开发依赖项的图像是否正确?
我不是在讨论开发依赖项
不是packages.json中列出的devDependencies
,我的意思是gcc,python,node-gyp,其他一些* -dev包,包含一堆头文件,静态库。
所有这些都需要编译一些节点依赖(如node-sass)
一个想法可能是一个两阶段构建,一个带有所有* -dev依赖关系的图像,在那里构建东西,并将结果导出到另一个只有二进制文件的新图像。
通常,我想在docker镜像中分发的任何已编译的软件都不应包含用于构建二进制文件的编译器,头文件和工具。
答案 0 :(得分:3)
如果您希望最终图像中不包含某些内容,则必须仅在一个图层(一个RUN语句)中执行所有相关命令。
类似以下内容(伪代码):
RUN install dev-dependencies && build your-project && uninstall dev-dependencies
只为RUN语句创建了一个图层,它不包含dev依赖项。
答案 1 :(得分:0)
如果删除依赖项,图像将不会更小,因为较旧的图层包含它们。
使用Docker 1.13尝试使用docker-build的新(实验)--squash选项。
答案 2 :(得分:0)
OP问题的答案取决于OP /他的公司为生产需求维护的图像数量。
可能的策略很少:
如果维护的图像数量从中到低,并且系统架构不是很复杂,并且一次不使用几十个图像,那么维护最简单,最简单的解决方案就是最好的。您可以通过1个单独构建来实现它。如果你想使用编译源作为可以承载不同内容的容器的基础(或者在docker-compose up
(系统启动)期间甚至可以完成第二阶段),或者2步构建。
你可以删除dev-only依赖项(如其他建议的答案),如果它需要保持图像苗条/有很多运行容器使用相同的图像/编译文件的大小是巨大的。这将增加构建过程的时间跨度,但会导致较小的图像。
第三种方法完全不同 - 如果有编译过程,请使用CI管道,独立编译单独容器内的资产(CI运行程序)并提供版本化工件 - 您可以在生产版本中使用(甚至商店)它在某个地方,在S3 / CDN /私有,可访问部署存储),然后从那里获取它,或者只使用那里托管的文件(如果是CDN)。