如何删除生产docker映像中的开发依赖项

时间:2022-11-23 06:51:58

When shipping a dockerized node.js to production, is it correct to ship an image that contains development dependencies?

在发送dockerized节点时。将包含开发依赖项的映像发送到生产环境,是否正确?

I am not talking about the development dependencies Not the devDependencies listed in packages.json, I mean gcc, python, node-gyp, some other *-dev packages, containing a bunch of headers, static libraries. All of them are needed to compile some node dependencies (like node-sass)

我说的不是开发依赖项,而是包中列出的devDependencies。json,我的意思是gcc, python, node-gyp,还有一些其他的*-dev包,包含一堆头文件,静态库。要编译某些节点依赖项(如node-sass),需要所有这些节点

An idea could be a two stage build, one image with all *-dev dependencies, build stuff in there, and export the results to another new image with just the binaries.

一个想法可以是两个阶段的构建,一个具有所有*-dev依赖项的映像,在其中构建东西,然后将结果导出到另一个只有二进制文件的新映像。

  • Pros: The final "production" image is small
  • 优点:最终的“生产”图像很小
  • Cons: Not standard way to build images
  • 缺点:不是构建图像的标准方法

In general, any compiled sofware I want to distribute in docker images, should not contain the compilers, headers, and tools used to build the binaries.

通常,我想在docker映像中分发的任何编译过的软件,都不应该包含用于构建二进制文件的编译器、头文件和工具。

3 个解决方案

#1


3  

If you want something to not be included in your final image, you have to do all the related commands in only one layer (one RUN statement).

如果您想要在最终的映像中不包含某些内容,您必须在一个层(一个RUN语句)中执行所有相关的命令。

Something like the following (pseudo code):

如下所示(伪代码):

RUN install dev-dependencies && build your-project && uninstall dev-dependencies

Only one layer is created for the RUN statement and it won't contain dev dependencies.

只为RUN语句创建了一个层,它不包含开发依赖项。

#2


0  

The image would not be smaller if you remove the dependencies because the older layers contain them.

如果删除依赖项,图像不会更小,因为旧层包含它们。

Try the new (experimental) --squash option with docker-build, using Docker 1.13.

使用Docker 1.13尝试新的(实验性的)挤压选项。

#3


0  

The answer to OP question depends of how much images OP/his company maintain for production needs.

OP问题的答案取决于OP/他的公司为生产需要维护多少图像。

There few strategies possible:

有几个策略:

  1. If the quantity of maintained images is medium to low and system architecture is not very complex and do not uses dozens of images at once there the simplest and easiest solution to maintain is the best one. You can approach it with 1 single build. Or 2 step build if you want to use compiled source as base for containers that could bear different content (In this case 2nd stage could be even done during docker-compose up (system start-up)).

    如果维护图像的数量是中等到低,系统架构不是很复杂,并且不同时使用几十个图像,那么维护最简单、最容易的解决方案就是最好的解决方案。您可以使用一个单独的构建来接近它。如果您想使用编译源作为容器的基础(在这种情况下,第二阶段甚至可以在docker- composer(系统启动)期间完成)。

  2. You can remove dev-only dependencies (as other answers suggested) if its necessary to keep the image slim/ there a lot of running containers that use same image / the size of compiled files is huge. This will increase time span of the build process but will result in smaller image.

    如果需要保持图像的苗条/有很多使用相同映像的运行容器/编译文件的大小很大,您可以删除只使用dev纯依赖项(如其他答案所示)。这将增加构建过程的时间跨度,但将导致图像变小。

  3. 3rd approach is totally different - if there is compiling process, use CI pipeline that independently compiles the assets within separate container (CI runner process) and provides versioned artifact - which you can use in your production builds (even store it somewhere, on S3/CDN/private, accesible to deployment storage), and then just fetch it from there, or just use files hosted there (in case of CDN).

    第三方法是完全不同的,如果是编译过程,使用CI管道内,独立编制资产单独的容器(CI跑步过程),并提供版本控制工件——你可以在生产中使用的构建(存储在某个地方,在S3 / CDN /私人,accesible部署存储),然后就从那里取,或只使用文件托管(CDN)的情况下。

#1


3  

If you want something to not be included in your final image, you have to do all the related commands in only one layer (one RUN statement).

如果您想要在最终的映像中不包含某些内容,您必须在一个层(一个RUN语句)中执行所有相关的命令。

Something like the following (pseudo code):

如下所示(伪代码):

RUN install dev-dependencies && build your-project && uninstall dev-dependencies

Only one layer is created for the RUN statement and it won't contain dev dependencies.

只为RUN语句创建了一个层,它不包含开发依赖项。

#2


0  

The image would not be smaller if you remove the dependencies because the older layers contain them.

如果删除依赖项,图像不会更小,因为旧层包含它们。

Try the new (experimental) --squash option with docker-build, using Docker 1.13.

使用Docker 1.13尝试新的(实验性的)挤压选项。

#3


0  

The answer to OP question depends of how much images OP/his company maintain for production needs.

OP问题的答案取决于OP/他的公司为生产需要维护多少图像。

There few strategies possible:

有几个策略:

  1. If the quantity of maintained images is medium to low and system architecture is not very complex and do not uses dozens of images at once there the simplest and easiest solution to maintain is the best one. You can approach it with 1 single build. Or 2 step build if you want to use compiled source as base for containers that could bear different content (In this case 2nd stage could be even done during docker-compose up (system start-up)).

    如果维护图像的数量是中等到低,系统架构不是很复杂,并且不同时使用几十个图像,那么维护最简单、最容易的解决方案就是最好的解决方案。您可以使用一个单独的构建来接近它。如果您想使用编译源作为容器的基础(在这种情况下,第二阶段甚至可以在docker- composer(系统启动)期间完成)。

  2. You can remove dev-only dependencies (as other answers suggested) if its necessary to keep the image slim/ there a lot of running containers that use same image / the size of compiled files is huge. This will increase time span of the build process but will result in smaller image.

    如果需要保持图像的苗条/有很多使用相同映像的运行容器/编译文件的大小很大,您可以删除只使用dev纯依赖项(如其他答案所示)。这将增加构建过程的时间跨度,但将导致图像变小。

  3. 3rd approach is totally different - if there is compiling process, use CI pipeline that independently compiles the assets within separate container (CI runner process) and provides versioned artifact - which you can use in your production builds (even store it somewhere, on S3/CDN/private, accesible to deployment storage), and then just fetch it from there, or just use files hosted there (in case of CDN).

    第三方法是完全不同的,如果是编译过程,使用CI管道内,独立编制资产单独的容器(CI跑步过程),并提供版本控制工件——你可以在生产中使用的构建(存储在某个地方,在S3 / CDN /私人,accesible部署存储),然后就从那里取,或只使用文件托管(CDN)的情况下。