如何使用复制到docker容器的python虚拟环境

Ore*_*n_C 6 python docker

我已经安装了一个 python 包,并根据需要进行了修改,并将其存储在 venv 文件夹中。我想使用:

RUN source venv/bin/activate
Run Code Online (Sandbox Code Playgroud)

在我的 Dockerfile 中(当然将其复制到容器中之后)可以解决我的问题,但对此答案的评论表明它不能。后来,我发现这篇文章展示了如何在 docker 容器内设置新的 venv,但没有回答我的问题。许多其他答案让我陷入了无休止的疯狂追逐,所以我决定在这里提问。希望一个好的答案能够解决我的问题,并为将来在 docker 容器中自定义 python 包时面临这个问题的人提供服务。

我的问题:
如何使用复制到 docker 容器中的 venv?

Dav*_*aze 4

一般来说,您无法在任何地方复制虚拟环境,无论是 Docker 还是其他方式。它们往往与非常特定的文件系统路径和非常特定的 Python 安装相关联。如果您知道自己有完全相同的 Python 二进制文件,并且将其复制到完全相同的文件系统路径,那么您可能可以按原样复制它,但构建系统将非常脆弱。

还有一种情况是,您通常不需要 Docker 中的虚拟环境。Docker 映像提供了与您在非 Docker 上下文中使用虚拟环境相同的隔离 Python 安装。如果您通常通过运行来设置虚拟环境

python3 -m venv vpy
. vpy/bin/activate
pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

那么你可以使用 Dockerfile 获得等效的安装,例如

FROM python:3
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

在评论中您暗示手动修改已安装的软件包。这通常不是最佳实践(如果您更改的包中有关键的安全更新怎么办?如果您的同事需要处理您的项目而不是在您的计算机上怎么办?)。您可以使用diff (1)等工具来制作补丁文件来描述更改的内容,并将修改后的文件与原始文件进行比较。如果你有的话,那么你可以做类似的事情

COPY local.patch /app/
RUN cd $(python3 -c 'import sysconfig; print(sysconfig.get_path("platlib"))') \
 && patch -p0 < /app/local.patch
Run Code Online (Sandbox Code Playgroud)

需要注意的是,每个 RUN 命令都会在新容器中启动一个新 shell。因此,cd最后一个示例中的命令影响此 RUN 命令,而不会影响后续命令。在您建议的RUN source ...命令中,由此设置的环境变量将在该 RUN 命令结束时丢失。(另请注意,这source不是标准 shell 命令,并且不适用于基于 Alpine 的图像等,但它.是等效的并且是标准的。)