首页 > 解决方案 > 为什么通过 ENTRYPOINT 和 tini 安装依赖项?

问题描述

我有一个关于在dask- docker上实现 Dockerfile 的问题。

FROM continuumio/miniconda3:4.8.2

RUN conda install --yes \
    -c conda-forge \
    python==3.8 \
    [...]
    && rm -rf /opt/conda/pkgs

COPY prepare.sh /usr/bin/prepare.sh

RUN mkdir /opt/app

ENTRYPOINT ["tini", "-g", "--", "/usr/bin/prepare.sh"]

prepare.sh只是方便通过 conda、pip 和 apt 安装其他软件包。

有两件事我不明白:

  1. 为什么不把这些指令放在 Dockerfile 中呢?可能通过复制专用文件(requirements.txt,environment.yaml,...)间接(模块化)
  2. 为什么要通过 tini 执行此操作?最后,它exec "$@"可以启动调度程序或工作程序 - 这就是我与 tini 相关的更多内容。

这样每次您从构建的映像运行容器时,您都必须重复安装过程!?

也许我想多了,但它似乎很不寻常——但也许这是一个有充分理由的 Dockerfile 模式。


Dask 内部人员的可选奖金问题:

标签: dockerdasktini

解决方案


这实际上取决于入口点脚本正在安装的文件的性质和用途。总的来说,我喜欢将其分为几类:

  1. 主机系统上经常更改的本地文件,将被滚动到最终映像中以进行生产发布。这适用于正在开发并需要在容器中测试的应用程序的源代码。您希望每次重建映像时将这些复制到运行时中。在 Dockerfile 中使用 COPY。

  2. 来自其他地方的频繁更改和/或特定于部署环境的文件。这就像来自 Hashicorp 保险库的秘密、网络设置、服务器配置等……可能会一直下载到容器中,即使它投入生产也是如此。入口点脚本应该下载这些文件,它应该根据主机注入的环境变量来决定从哪里获取哪些文件。

  3. 库、可执行程序(在/bin/usr/local/bin等...下)以及除计划升级期间外特别不应更改的内容。通常使用 安装的任何东西pipmaven或执行依赖管理的其他程序,以及使用apt-get或等效安装的任何东西。这些文件不应从 Dockerfile从入口点脚本。更好的是构建您的基础镜像,并安装所有依赖项,然后使用该镜像作为 FROM 源进行进一步开发。这有许多优点:它确保了一个稳定的、位于中心位置的起始平台,每个人都可以使用它进行开发和测试(它在重要的地方强制统一);它可以防止您对托管这些库的服务器进行攻击(不断地从 pypy.org 重新下载所有这些库是一种非常糟糕的形式……必须有人为该带宽付费);它使构建速度更快;如果您有单独的安全团队,这可能有助于减少他们需要扫描的文件数量。

您可能正在查看#3,但我将所有三个都包括在内,因为我认为这是对事物进行分类的有用方法。


推荐阅读