如何在 Linux 上打包 Python 应用程序

了解如何使用 dh_virtualenv 使您的 Python 应用程序可以作为 .deb 包安装。
111 位读者喜欢这个。
Python in a tree

来自 Wikimedia Commons 的原始图片 CC0

在基于 Debian 的操作系统(如 Debian 或 Elementary OS)上安装 Python 应用程序的一种方法是使用 dh_virtualenv 工具。它构建一个 .deb 包,该包将 Python 虚拟环境包装在应用程序周围,并在安装时部署它。

在本文中,我将通过构建包含 HTTPie 工具的包的示例,解释如何使用它来从命令行测试 HTTP API,而无需激活虚拟环境。

使用 dh_virtualenv 打包

首先,您需要安装 dh_virtualenv 所需的工具。dh_virtualenv 的 文档 提供了所有安装选项。在我的基于 Debian 的系统上,我输入了

apt-get install dh-virtualenv devscripts

虽然 devscripts 包不是必需的,但它将简化后续操作。

现在,创建一个目录来保存源代码。由于这是 HTTPie 的本地、非官方打包,我将其称为 myhttp。接下来,让我们在 myhttp 内部创建一些文件,以便为 Debian 构建系统提供元数据。

首先,创建 debian/control 文件

Source: myhttp
Section: python
Priority: extra
Maintainer: Jan Doe <jandoe@example.org>
Build-Depends: debhelper (>= 9), python3.7, dh-virtualenv (>= 0.8)
Standards-Version: 3.9.5

Package: myhttp
Architecture: any
Pre-Depends: dpkg (>= 1.16.1), python3.7, ${misc:Pre-Depends}
Depends: ${misc:Depends}
Description: http client
 Useful for doing stuff

那么所有这些信息是关于什么的呢?正如 Debian 文档 所说

“第 1-7 行是源软件包的控制信息。第 9-13 行是二进制软件包的控制信息。”

这是我的看法

  • section 值在我们的案例中大多没有意义,但需要存在。它对于向引导式 UI 安装程序提供信息很有意义,但这与此包无关。
  • 额外的 Priority 值是像这样的第三方软件包的正确优先级。
  • 强烈建议在 Maintainer 字段中填写真实的联系方式。它不必是您的个人电子邮件,例如,如果软件包由团队维护,并且您希望将问题发送到团队的邮件别名,则可以使用“Infrastructure Team <infra-team-list@company.example.com>”。
  • build-depends 字段指示您需要 debhelper、python 和 dh-virtualenv 来构建软件包:软件包构建过程将确保在软件包构建时安装这些依赖项。
  • standards version 主要供人类阅读。它指示您正在遵循哪个指南。本指南基于 dh-virtualenv 的官方文档,该文档基于 Debian 的 3.9.5 指南。几乎总是最好将二进制软件包和源软件包命名为相同。
  • Architecture 字段应为 Any,因为虚拟环境可能包含一些特定于体系结构的文件:否则,该字段最好选择为 all
  • 保持 pre-depends 列表不变:pre-depends 是一种非常严格的依赖形式,您很少需要比此处建议的最小值更多的东西。依赖项通常由构建系统准确计算,因此没有理由手动指定它们。
  • 如果您的软件包主要供内部使用,那么 Description 可能只指定最少的信息和公司 wiki 的链接;否则,更多详细信息可能很有用。

然后创建 debian/compat 文件,该文件 主要出于历史目的而存在

$ echo "9" > debian/compat

接下来,创建变更日志以告知软件包用户自上次发布以来发生了哪些更改。最简单的方法是使用 dch --create 创建模板,然后填写值。

填写后,它看起来像

myhttp (2.0.0-1) stable; urgency=medium

  * Initial release.

 -- Jan Doe <jandoe@example.org>  Fri, 27 Mar 2020 01:09:22 +0000

现在您需要告诉工具安装 HTTPie,但是哪个版本?

创建一个具有宽松版本的 requirements.in 文件

httpie

通常,宽松的需求文件将仅包含项目的直接依赖项,并在需要时指定最低版本。不总是需要指定最低版本:这些工具通常倾向于将依赖项收紧到“尽可能最新的版本”。在 Debian 软件包对应于一个内部 Python 软件包的情况下(内部应用程序中的常见情况),宽松的需求文件将看起来相似:只有一行包含软件包的名称。

然后使用 pip-compile(可以通过安装 PyPI 软件包 pip-tools 获得)

$ pip-compile requirements.in > requirements.txt

这将生成一个名为 requirements.txt 的严格依赖项文件

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile requirements.in
#
certifi==2019.11.28       # via requests
chardet==3.0.4            # via requests
httpie==2.0.0             # via -r requirements.in
idna==2.9                 # via requests
pygments==2.6.1           # via httpie
requests==2.23.0          # via httpie
urllib3==1.25.8           # via requests

最后,编写一个 debian/rules 文件来创建软件包。由于 dh_virtualenv 完成了所有繁重的工作,因此规则文件很简单

#!/usr/bin/make -f

%:
	dh $@ --with python-virtualenv --python /usr/bin/python3.7

请务必指定 Python 解释器。默认情况下,它将使用 /usr/bin/python 中的解释器,它是 Python 2,但您应该使用 受支持的 Python 版本

编写已完成;剩下要做的就是构建软件包

$ debuild -b -us -uc

这将生成父目录中的一个文件,其名称类似于 myhttp_2.0.0-1_amd64.deb。此文件可以安装在任何兼容的操作系统上。

通常,最好在相同的平台上构建旨在用于特定平台(如 Debian 10.0)的 Debian 软件包。

您可以将此 Debian 软件包存储在存储库中,并在所有相关系统上安装它,例如使用 Ansible

结论

为基于 Debian 的操作系统打包应用程序是一个多步骤的过程。使用 dh_virtualenv 将使该过程变得简单明了。

接下来阅读
标签
Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
自 1998 年以来,Moshe 一直参与 Linux 社区,帮助举办 Linux“安装派对”。自 1999 年以来,他一直在编写 Python 程序,并为核心 Python 解释器做出了贡献。Moshe 在这些术语出现之前就一直是 DevOps/SRE,他非常关心软件可靠性、构建可重复性以及其他此类事情。

2 条评论

准备好为 linux 打包我的第一个 python 应用程序

感谢这份不错的manual。不幸的是,它对我不起作用,因为它一直显示“virtualenv: error: unrecognized arguments: --no-site-packages”。在其他论坛搜索后,我仍然卡住,因为我不知道如何更改 dh-virtualenv 的这个默认设置。
感谢任何提示

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.