如何在Dockerfile中创建函数?

4smxwvx5  于 2022-12-11  发布在  Docker
关注(0)|答案(2)|浏览(133)

我有一些非常大的docker文件,我想重构和代码共享。
它们中的很多共享很多构建步骤(例如,从github安装特定的依赖项),但其中一些有不同的基础映像。
有没有一个好的方法来创建函数来抽象和共享这个逻辑。理想情况下,我会创建一个Docker库,其中包含如下函数:

def install_opencv():
   ... DO stuff ...

def install_aws_streams():
   ... DO stuff ...

... other helpful install commands ...

然后我可以将它们导入到相关的Docker文件中:
停靠文件A

import my_custom_docker_lib

From baseX
install_opencv()
install_aws_streams()

停靠文件B

import my_custom_docker_lib

From baseY
install_opencv()
install_aws_streams()
z2acfund

z2acfund1#

Dockerfile没有“函数”或“子程序”的概念,它以线性顺序执行RUN指令和其他命令;甚至没有循环或条件语句。
原则上,可以使用一系列Dockerfile来构建类似的内容,但是您需要一个非常手动的构建系统。那么您可以有一个Dockerfile片段,它分别安装了这些片段中的每一个,并使用一系列docker build --build-arg base_image=...命令将它们缝合在一起。
如果可以在一个RUN命令中完成这些安装,那么您可以构建一个安装函数的shell脚本

install_opencv() {
  apt-get update
  apt-get install ...
}

install_aws_streams() {
  ...
}

然后,您可以将此安装命令库引入映像中,并对它们执行RUN操作。

FROM ubuntu:22.04
COPY installers.sh /usr/local/bin
RUN . installers.sh && install_opencv
RUN . installers.sh && install_aws_streams

(请记住使用标准Bourne shell语法,而不是bash扩展,尤其是当您要针对Alpine图像时:shell函数不会以单词function开始,并且更喜欢使用.而不是非标准的source。另外请注意,如果安装程序函数脚本发生了任何变化,整个构建序列都将重复。)
这个设置与我期望的典型映像的工作方式有一点冲突。一个映像通常只打包一个应用程序。该映像也可以在容器之外工作,并且特定语言的依赖文件会列出它所需要的东西。然后我期望Dockerfile最多有一个发行包管理器“install”命令,该命令安装构建C扩展所需的东西。然后使用一个laiguage-package-manager“install”命令来安装实际的应用程序依赖项。

k75qkfdt

k75qkfdt2#

每个Docker映像都由层组成,您需要构建有效的层模型。这种方法与用某种过程语言编写程序不同,在这种语言中,您希望将意大利面条式的代码解耦到逻辑模块中。
如果您对现有的图层有信心,那么您可以使用模板方法,就像许多流行的图片一样,如Postgres

...
COPY docker-entrypoint.sh /usr/local/bin/
{{ if .major >= 11 then "" else ( -}}
RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
{{ ) end -}}
ENTRYPOINT ["docker-entrypoint.sh"]
...

相关问题