最小化 docker 使用 Nix 的 `dockertools.buildImage` 构建的容器大小
Minimize docker container size built with Nix's `dockertools.buildImage`
我正在使用 nix 的 dockerTools
将 python 应用程序打包到 docker 中,除了图像大小外,一切都很好。 Python本身大约40Mb,加上numpy
和pandas
就几百兆,而应用程序代码只有~100Kb。
我看到的唯一解决方案是将依赖项打包到单独的图像中,然后从中继承主图像,它不会固定大小,但至少我不需要在每次提交时传输巨大的图像。我也不知道该怎么做,我应该使用带有 nix 的图像,还是使用 pythonPackages.buildEnv
构建环境并将我的应用程序附加到它?
最好有一些通用的解决方案,但 python 具体的解决方案会更好。即使您有不完美的解决方案,也请分享。
好的,使用 fromImage
attr for buildImage
我将一个巨大的层拆分为巨大的依赖层和小的应用程序代码层。
我想知道是否有任何方法可以将这个胖依赖层移动到单独的图像中,以便我可以在我的其他项目中共享它?
没有必要将您的依赖项打包到单独的映像中并继承它,尽管那样不会造成伤害。
您需要做的就是确保将应用程序代码添加为 Dockerfile 中的最后一步。每个命令都有自己的层,因此如果您只更改应用程序代码,则可以从缓存中使用该更改之上的所有层。
Docker Images and Layers 文档中的示例:
dockerfile
FROM ubuntu:15.10
COPY . /app
RUN make /app
CMD python /app/app.py
包含四个不同的层。如果只修改最后一行,则只需要传输该层及其下的所有层。推或拉时,您会在缓存中使用的图层旁边看到 4b0ba2c4050a: Already exists
。
按照这种方法,您最终不会得到较小的图像,但正如您所说,您不必在每次更改时都拉出大图像。
谷歌搜索了一下并阅读了 dockerTools
代码后,我以这个解决方案结束:
let
deps = pkgs.dockerTools.buildImage {
name = "deps";
content = [ list of all deps here ];
};
in pkgs.dockertools.buildImage {
name = "app";
fromImage = deps;
}
这将构建两层 docker 图像,其中一层是依赖项,另一层是应用程序。 fromImage
的值似乎也可能是 pullImage
的结果,它应该给你相同的结果(如果我理解正确的代码),但我无法检查它。
我正在使用 nix 的 dockerTools
将 python 应用程序打包到 docker 中,除了图像大小外,一切都很好。 Python本身大约40Mb,加上numpy
和pandas
就几百兆,而应用程序代码只有~100Kb。
我看到的唯一解决方案是将依赖项打包到单独的图像中,然后从中继承主图像,它不会固定大小,但至少我不需要在每次提交时传输巨大的图像。我也不知道该怎么做,我应该使用带有 nix 的图像,还是使用 pythonPackages.buildEnv
构建环境并将我的应用程序附加到它?
最好有一些通用的解决方案,但 python 具体的解决方案会更好。即使您有不完美的解决方案,也请分享。
好的,使用 fromImage
attr for buildImage
我将一个巨大的层拆分为巨大的依赖层和小的应用程序代码层。
我想知道是否有任何方法可以将这个胖依赖层移动到单独的图像中,以便我可以在我的其他项目中共享它?
没有必要将您的依赖项打包到单独的映像中并继承它,尽管那样不会造成伤害。
您需要做的就是确保将应用程序代码添加为 Dockerfile 中的最后一步。每个命令都有自己的层,因此如果您只更改应用程序代码,则可以从缓存中使用该更改之上的所有层。
Docker Images and Layers 文档中的示例:
dockerfile
FROM ubuntu:15.10
COPY . /app
RUN make /app
CMD python /app/app.py
包含四个不同的层。如果只修改最后一行,则只需要传输该层及其下的所有层。推或拉时,您会在缓存中使用的图层旁边看到 4b0ba2c4050a: Already exists
。
按照这种方法,您最终不会得到较小的图像,但正如您所说,您不必在每次更改时都拉出大图像。
谷歌搜索了一下并阅读了 dockerTools
代码后,我以这个解决方案结束:
let
deps = pkgs.dockerTools.buildImage {
name = "deps";
content = [ list of all deps here ];
};
in pkgs.dockertools.buildImage {
name = "app";
fromImage = deps;
}
这将构建两层 docker 图像,其中一层是依赖项,另一层是应用程序。 fromImage
的值似乎也可能是 pullImage
的结果,它应该给你相同的结果(如果我理解正确的代码),但我无法检查它。