打包Python代码的选项:轮子、Conda、Docker等

2020-08-11 14:12:04

您已经编写了Python应用程序(服务器、CLI工具或批处理),现在需要将其分发到要运行该应用程序的计算机上。要运行您的应用程序,您需要:

其他语言(C、C++等)中的共享库。您的代码及其Python依赖项所依赖的。

您到底是如何打包应用程序以便所有这些都可用的呢?当然有Docker,但实际上还有更多选项,从轮子到系统包到Conda到PEX再到自包含的可执行文件,每个选项都有它们自己的权衡。这只是一个部分列表!

由于可供选择的范围很广,因此每个选项都有太多的详细介绍。相反,本文将给出不同类别的感觉、优缺点,并提供指向每个类别中的具体实现的链接。为简单起见,我将只介绍在Linux上运行的内容。

分发您的应用程序的一种选择是将其打包为可以用管道安装的东西,这意味着一个二进制轮子、一个包含源代码的tarball,甚至是一个git存储库:pip可以安装这些东西中的任何一个。

基本上,您唯一要打包的就是代码。Python依赖项可以指定为打包中的依赖项,并通过管道自动安装。您可以将第三方C库包含在控制盘中,但对于足够复杂的依赖项,这些依赖项将不起作用。

因此,一些额外的C库或程序,当然还有Python可执行文件,必须使用其他机制安装,例如系统包(RPM/DEB)。

您的系统库和Python版本是跨应用程序标准化的,因此您只需在服务器群中预安装所有必需的库和Python版本即可。

或者,您正在打包一个简单的Python应用程序,该应用程序只需要PyPI或您的私有PyPI等价服务器上提供的内容即可。

您的应用程序需要自定义的C/C++/等库,这些库不能通过pip安装,也不能假定已预安装。

具体地说,虽然可以使用viralenvs支持多个需求冲突的应用程序,但是如果您要通过系统包安装不同版本的C库,这会变得更加棘手。

PEX、SUBPAR和SHIV都是将Python代码及其Python依赖项打包到单个可执行文件中的方法。PEX似乎是最受欢迎和支持最好的方法,所以如果您选择使用这个类别,那就是我要使用的。

如果您希望分发包含所有Python代码的单个可执行文件,则它们非常有用。除此之外,它们还存在与仅使用pip安装相同的问题:您可能还需要将依赖项作为系统包(RPM/DEB)分发。

与pip不同,没有分发机制:您需要以某种方式分发PEX文件。

另一种选择是使用RPM(对于CentOS/RHEL)或DEB包(对于Debian/Ubuntu)打包您的代码。Python依赖项要么包含在包中(例如,您可以打包整个viralenv),要么作为对其他系统包(RPM或Debs)的依赖项。C库也可以是对其他系统包的依赖项,也可以包含在包本身中。

解释器通常会根据--您猜对了--另一个系统包来安装。

基本上,您最终安装了一个RPM/DEB,然后它依赖于一大堆其他RPM/DEB。

如果您正在运行虚拟机并且想要运行单个应用程序,这是一个很好的选择。

您需要的特定软件包是您正在使用的特定操作系统版本上的错误版本。

您希望在同一台计算机或虚拟机上运行具有多个依赖项的多个应用程序。这在理论上是可能的,但由于冲突或包不可用,最终可能会很困难。

CONDA包系统将Python包和C共享库以及Python解释器打包到CONDA包中。

它在基本操作系统上唯一使用的是标准C库。

如果您正在使用Conda-Forge包频道,您还可以访问大量现有的开源包。从个人体验来看,向Conda-Forge添加包是一种出乎意料的愉快体验。

通常情况下,您的实际应用程序不是Conda包,它只是您的代码加上要安装的Conda包列表,因此您仍然需要以某种方式分发您的应用程序。

Conda非常擅长在同一台机器或虚拟机上支持具有不同依赖关系的多个应用程序(包括Python版本和C库版本)。

PyInstaller和PyOxidizer等工具允许您创建自包含的可执行文件,其中包括Python解释器、代码和Python依赖项。通常不包括外部共享C库。

如果您不使用任何特殊的C共享库,而不使用任何Linux发行版所期望的最低限度,那么这是一个很好的选择。

像Docker和Singulicity这样的容器系统可以让您分发一个完整的、隔离的文件系统,包括运行应用程序所需的所有内容,从C库到Python解释器,再到您的代码,再到您的依赖项,应有尽有。

如果您需要运行许多不同的组合和变体,并且需要一定程度的隔离,这是一个很好的解决方案。

缺点是您有多层打包:您可能必须同时进行Docker打包并依赖前面介绍的一种机制。

以下是以上所有选项的比较,就它们包含的内容而言。I表示包含特定需求,D表示可以将其指定为依赖项。

了解如何构建快速、可投入生产的Docker映像-阅读针对Python的Docker打包指南的其余部分。

从为您节省时间的快速构建到保证您安全的安全最佳实践,您如何快速获得打包Python应用程序用于生产所需的专业知识?

通过使用Docker Production QuickStart上的Python,快速了解最佳实践。

你需要在就业市场上保持竞争力--但是要学的东西太多了,你不知道从哪里开始。

加入2100多名Python开发人员和数据科学家的行列,学习实用工具和技术,从Docker打包到Python最佳实践,每周在您的收件箱中都会有一篇免费的新文章。