4、requirements.txt:生成、安装与版本控制
说实话,requirements.txt 这东西,看着简单,坑可不少。我见过太多团队因为一个版本没锁死,导致线上环境炸锅。今天咱们就把它彻底聊透。
4.1 生成 requirements.txt
生成这个文件,说白了就是把当前环境里装的包都列出来。我个人习惯用 pip freeze,简单粗暴:
pip freeze > requirements.txt
跑完这条命令,你会看到类似这样的输出:
ansible==4.3.0
cryptography==3.4.8
Jinja2==3.0.1
netmiko==3.4.0
paramiko==2.7.2
PyYAML==5.4.1
嗯,这里要注意。直接 pip freeze 会把所有包都列出来,包括那些依赖包。你想想看,有时候你只想记录顶层依赖,这时候可以用 pipreqs:
pip install pipreqs
pipreqs ./ --encoding=utf-8
它会扫描你的代码,只提取真正用到的包。我在项目中遇到过好几次,用 pip freeze 生成的列表里有一堆无关包,结果部署时反而出问题。
4.2 从 requirements.txt 安装
安装就一句话:
pip install -r requirements.txt
但这里有个坑。我曾经在部署自动化脚本时,发现同样的 requirements.txt,在不同机器上装出来的包版本不一样。为什么?因为 -r 参数只安装文件里列出的包,但如果某个包依赖另一个包,而那个依赖包没指定版本,pip 就会装最新版。
举个例子:
# requirements.txt
netmiko==3.4.0
Netmiko 依赖 paramiko,但你没锁 paramiko 的版本。结果机器 A 上装了 paramiko 2.7.2,机器 B 上装了 2.8.0。两个版本之间可能有 API 变化,你的脚本就炸了。
pip freeze 生成的完整列表,而不是手动写几个包名。
4.3 版本锁定与范围指定
版本控制是 requirements.txt 的核心。说白了,就是告诉 pip:「你要装哪个版本,或者哪个范围内的版本」。
常见的写法有这几种:
| 写法 | 含义 | 示例 |
|---|---|---|
== |
精确锁定版本 | netmiko==3.4.0 |
>= |
大于等于某个版本 | paramiko>=2.7.0 |
<= |
小于等于某个版本 | cryptography<=3.4.8 |
~= |
兼容版本(主版本相同即可) | ansible~=4.0 表示 4.x 系列 |
!= |
排除某个版本 | paramiko!=2.7.1 |
我个人建议,在生产环境中尽量用 == 精确锁定。你想想看,网络设备配置下发这种操作,容不得半点差错。版本不一致导致的 API 变化,可能让你丢数据。
但开发环境可以灵活一点。比如:
# 开发环境
netmiko>=3.0.0, <4.0.0
paramiko>=2.7.0
这样既能用上新功能,又不会因为大版本升级而炸锅。
4.4 知识体系图
下面这张图,帮你理清 requirements.txt 的核心逻辑:
4.5 实战建议
最后,给你几个我踩坑后总结的建议:
- 每次部署前,都重新生成一次 requirements.txt。别用三个月前的文件。
- 把 requirements.txt 纳入版本控制(Git)。这样你能看到每次改了哪些包。
- 用虚拟环境。我习惯每个项目一个虚拟环境,互不干扰。
- 测试环境和生产环境用同一个 requirements.txt。别搞两套。
好了,requirements.txt 的核心内容就这些。记住一句话:版本锁死,环境一致,部署无忧。