我们开始将我们的docker容器迁移到24.04版本,并在安装python依赖项期间从操作系统获得了以下建议:
root@76ea3b9e695a:/# pip install numpy
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
See /usr/share/doc/python3.12/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS
distribution provider. You can override this, at the risk of breaking your Python
installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
问题:
- 假设 python-* 没有涵盖我们所有的依赖项,那么 venv 方法是否确实是在 24.04容器中安装 python 依赖项以公开单个入口点应用程序的推荐方法,例如
__main__.py
? - 使用 python-* 作为依赖项有什么好处?ubuntu是否提供漏洞支持?
TLDR;使用 venv 进行项目(并使用工具来控制和解决你的依赖)
我确信做事有很多种方法,但我的论点如下:
是的,安装到 venv 确实是首选,原因如下:
python-*
将 pip 包安装到操作系统中可能会破坏依赖于正确的 apt包(可能会被 pip 修改)的其他操作系统。Apt
python-*
软件包主要针对依赖于它们的操作系统。操作系统是使用给定的依赖项进行设计和测试的,并且能够很好地协同工作。只要您只在这些依赖项内移动,它们就很可能彼此很好地协同工作。这些软件包有时会更新,但可能不会包含每个新版本,因为这需要太多测试才能确保所有操作系统继续工作。当然,这些软件包的安全修复程序可能由 apt 软件包维护者提供,但同样,更新可能不太频繁或不那么快。例子
如何使用 uv 工具构建确定性 Docker 构建的示例可在此处找到。我特别喜欢这种多阶段 Docker 构建,因为在正在运行的容器中,uv 不是必需的,因为只有 venv 被复制到那里。(请注意,此处的示例实际上在两个映像中使用了系统解释器,因此仍然存在系统依赖性。)
观点
总的来说,有了好的工具,管理依赖关系就会变得容易得多。Uv 是 Python 社区中最新的工具,我几乎在所有新项目中都使用它。由于它有自己的一套规则,并且只适用于 venvs,因此上面的工作流程几乎成为使用它的必要条件。
如果您对简单脚本只有一些要求,那么直接安装它们可能就没问题,而不需要 venv,只是这些项目会随着时间的推移而增长并变得更加复杂。所以是的,第一次就做对了 ;)