Skip to main content
 首页 » 编程设计

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

2024年11月24日29zlslch

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

RUN source venv/bin/activate 

在我的 Dockerfile 中(当然是在将其复制到容器中之后)可以解决我的问题,但是对 this answer 的评论显示它没有。后来偶遇this article这显示了如何在 docker 容器内设置一个新的 venv,但没有回答我的问题。许多其他答案让我无休止地追逐,所以我决定在这里问问。希望一个好的答案能解决我的问题,并为将来在 docker 容器中自定义 python 包时遇到这个问题的人服务。

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

请您参考如下方法:

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

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

python3 -m venv vpy 
. vpy/bin/activate 
pip install -r requirements.txt 

然后你可以用像这样的 Dockerfile 得到一个等效的安装

FROM python:3 
WORKDIR /app 
COPY requirements.txt . 
RUN pip install -r requirements.txt 

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

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

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