为什么人们在 docker 容器中创建 virtualenv?

Why do people create virtualenv in a docker container?

您可以在几秒钟内用 Dockerfile 构建一个容器。 那么为什么人们需要在 docker 容器中安装虚拟环境?

好像是虚拟机中的“虚拟机”?

我在 Docker 中使用 virtualenvs,我认为有几个原因:

  1. 您可能希望将您的应用与系统的 python 软件包隔离开来
  2. 您可能想要 运行 python 的自定义版本,但仍保持系统包不变
  3. 您可能需要对为特定应用安装的软件包进行精细控制
  4. 您可能需要运行多个具有不同要求的应用程序

我认为这些都是在安装结束时添加一点 pip install virtualenv 的合理理由! :)

这是我的两分钱,或者更确切地说是对@gru 的回答和一些评论的评论。

  • docker 和虚拟环境都不是虚拟机
  • docker 文件中的每一行都会产生开销。但确实 运行 时间虚拟环境的影响为零
  • docker 容器的想法是,您有一个进程在客户端-服务器关系中与其他 (docker-) 服务交互。 运行 一个 docker 中的不同应用程序或从一个 docker 中的另一个应用程序调用一个应用程序在某种程度上违背了这个想法。更重要的是,它增加了您想要避免的复杂性 docker。
  • "isolating" 应用程序从安装在 docker 中的包中看到(在虚拟环境中)的 python 包仅当您需要确保特定版本时才需要一个或多个包裹。
  • 安装在容器内的系统仅作为您正在 运行ning 的一个应用程序的环境。根据您的应用程序的要求进行调整。不用留了"untouched"

所以在结论:没有充分的理由在容器内使用虚拟环境。在系统上安装您需要的任何软件包。如果您需要控制确切的软件包版本,请使用 pip 或类似的方式安装 (docker-wide)。

如果您认为需要 运行 在单个容器中使用不同包版本的不同应用程序,请退后一步并重新考虑您的设计。您正朝着更复杂、更难维护和更头疼的方向前进。将 work/services 分成几个容器。

在我们的团队中,我们避免在 Docker 个容器内创建 Python 个虚拟环境。

它增加了另一层复杂性,在大多数情况下几乎没有用。

在极少数情况下,可能需要不更改您需要的系统工具,这些工具是用 Python 编写的,并且需要某些特定版本的 Python 库,否则这些工具将被覆盖构建时你自己的 Python 包管理器。

人们也可能这样做,因为他们习惯了虚拟环境并在 Docker 图像中继续使用它们而没有问自己太多问题:它仍然有效,并且可能是他们在教程中找到的默认设置.

现在,为了安全起见,这些教程可能建议在 Docker 图像中创建一个虚拟环境,并避免与系统的 python 工具发生所有可能的冲突。

例如,Poetry是一个包管理器,但它也坚持为您使用或创建虚拟环境。我认为这不是适当的关注点分离:如果需要,最好有一个包管理工具和另一个虚拟环境管理工具。

但是因为 Poetry 混淆了这些东西(在一个可以理解的 one-tool-that-solves-it-all 的尝试中),我们不得不在我们的 Docker 文件上迭代几次才能找到一个简单的解决方法:

FROM python:3.10-slim
RUN pip install -U pip poetry

# creates working directory
RUN mkdir -p /app/src
WORKDIR /app/src

# installs dependencies
ADD poetry.lock pyproject.toml /app/src/
RUN poetry export -f requirements.txt --output requirements.txt
RUN pip install --no-deps -r requirements.txt

# copies the rest of the source code
ADD . /app/src/

# …

不需要 virtualenv,并且当使用 pip 简单地安装依赖项时,构建现在似乎更快。