导语:
近期多个生态事件再次提醒我们:Python 项目出问题往往不是代码逻辑,而是依赖漂移、包被投毒、构建不可重现。要在生产场景做到可控,必须把“锁文件 + 重现构建 + 签名校验”做成默认流程。本文给出一份可直接执行的落地手册,并附检查清单。
1. 目标
- 依赖可重现:同一锁文件在任意环境安装得到同样的包与哈希。
- 制品可信:wheel/镜像有签名并在部署侧校验。
- 发布可追溯:构建溯源(源码、依赖、Python版本、构建命令)可查询。
2. 锁文件策略
- 统一入口:使用
pyproject.toml+ 包管理器(如pip-tools、poetry、uv)生成锁文件。 - CI 校验:修改依赖未更新锁文件 → 直接失败。
- 哈希强制:锁文件必须包含包哈希,禁止
--no-deps或latest模式漂移。 - 依赖升级节奏:设定“依赖升级窗口”(如每周一次),由机器人提 PR。
3. 重现构建
- 使用固定基础镜像(含特定 Python 版本与构建工具)。
- 构建产物:wheel/sdist + 构建 metadata(commit、锁文件哈希、构建命令)。
- 本地与 CI 统一:提供
make build或task build,确保命令一致。 - 运行环境一致:生产环境禁止临时
pip install;全部来自制品仓库。
4. 签名与校验
- 构建后对 wheel/镜像做签名(KMS 管理密钥)。
- 部署/运行时强制校验签名与哈希;失败直接拒绝。
- 将签名与哈希写入发布记录(证据包)。
5. CI/CD 门禁示例(可直接照抄)
CI
- lint + 类型检查(核心模块可要求 mypy 严格模式)。
- 单测 + 覆盖率阈值。
- 依赖锁校验:
pip hash或工具内置校验。 - SBOM 生成(CycloneDX)并存档。
CD
- 取构建产物 + 签名,做一次安装演练(smoke test)。
- 灰度发布:1%→10%→全量,设停止条件(错误率/时延/资源)。
- 回滚:保留上一版本镜像与签名校验,通过开关/流量切回。
6. Evidence Pack 模板
发布或上线后,保留:
- 变更单/PR ID
pyproject与锁文件版本/哈希- 构建环境与命令摘要
- 制品哈希与签名
- 测试/覆盖率摘要
- 灰度/回滚记录与验证结果
7. 常见坑与对策
- “只锁顶层”:必须锁全依赖树与哈希。
- “随手 pip install”:生产禁止临时安装;发现后应补录并重建版本。
- “签名只做不验”:部署侧必须强校验,否则签名形同虚设。
结语:
Python 交付的可控性来自“可重现 + 可验证”。把锁文件、重现构建与签名校验做成流水线默认项,才能在高频迭代中保持稳定与安全。
补充:包来源与镜像安全
- 统一私有镜像或代理,禁止直接拉公网;对公网包做“批准列表”与来源备案。
- 启用下载哈希校验与缓存防篡改;异常哈希直接阻断。
- 对高风险依赖启用“强签名校验”(如 Sigstore/自签+校验),并在部署侧二次验证。
补充:本地开发到生产一致性的检查表
- Python 版本:本地/CI/生产一致,或通过 pyenv/容器固定。
- 环境变量:提供
.env.example,CI 检查缺失/多余变量。 - 任务脚本:本地/CI/生产统一入口(
make lint/test/build),避免命令漂移。