本文档旨在阐明 Vehicle_Mock_fixed 项目从最初的问题诊断到最终成功部署的全过程,并详细解释为什么我们当前的 Dockerfile 和 .github/workflows/*.yml 文件与公司原始仓库的配置存在差异。
在 OWA5X 设备上运行新构建的 vehicle-mock 镜像后,容器立即退出,日志显示以下错误:
ModuleNotFoundError: No module named 'jaraco'
[9] Failed to execute script 'pyi_rth_pkgres' due to unhandled exception!
- PyInstaller 的静态分析局限:
PyInstaller在打包Python应用时,会分析代码找出所有依赖项。但它无法完美处理所有动态导入或隐藏的依赖。 pkg_resources的隐藏依赖:pkg_resources这个库(setuptools的一部分)在运行时会动态加载jaraco系列的模块。PyInstaller 未能自动检测到这个“隐藏”的依赖关系。- 结果:打包出的
run-exe可执行文件中缺少了jaraco模块,导致容器一启动就因找不到模块而崩溃。
我们通过修改 Dockerfile,在 pyinstaller 命令中明确告知它需要包含这些缺失的模块。
vehicle-mock/Dockerfile (第 47 行):
# 原始命令
# RUN pyinstaller --clean -F -s --paths=src mockprovider.py
# 修复后的命令
RUN pyinstaller --clean -F -s --paths=src \
--hidden-import jaraco.text \
--hidden-import jaraco.functools \
--hidden-import jaraco.context \
mockprovider.py--hidden-import:这个参数强制 PyInstaller 将指定的模块打包进最终的可执行文件,从而解决了运行时的ModuleNotFoundError。
我们的目标是修复 vehicle-mock 的核心问题,并建立一个可靠、独立的CI/CD流程。这个过程经历了几个阶段,导致了配置上的差异。
- 核心任务:解决
vehicle-mock覆盖ExteriorLightControl信号导致灯光控制冲突的问题。 - CI/CD 目标:创建一个能在你自己的GitHub仓库 (
Vehicle_Mock_fixed) 中自动构建和发布镜像的现代化工作流(Workflow)。 - 最初的修改:
- 注释掉
vehicle-mock/app/mock.py中关于ExteriorLightControl的代码。 - 创建了新的
.github/workflows/文件,支持 multiarch (amd64 + arm64) 构建,比原始仓库仅支持arm64更先进。
- 注释掉
- 问题:当我们尝试进行
multiarch构建时,arm64平台的构建失败了。 - 错误信息:
ModuleNotFoundError: No module named 'SCons'。 - 原因:
- 在GitHub Actions的 QEMU模拟arm64环境 中,
staticx库没有预编译包,需要从源码构建。 staticx的源码构建依赖SCons工具。pip默认使用“构建隔离”(build isolation),它会创建一个临时、干净的环境来构建包。这个隔离环境看不到我们在上一步用apt-get安装的SCons。
- 在GitHub Actions的 QEMU模拟arm64环境 中,
- 当时的解决方案:
- 在
Dockerfile中为staticx的安装命令添加--no-build-isolation参数。这使得pip可以在系统环境中构建,从而找到SCons。
- 在
- 你的要求:你提出只需要构建
arm64,并希望配置能和公司原始仓库尽可能保持一致。 - 我们做的修改:
- 修改 Workflow (
.yml文件):- 将
multiarch构建目标改回了固定的platform: "linux/arm64"。 - 将镜像标签从动态生成(如
:latest,:sha)改为了固定的:v001arm。
- 将
- 回退 Dockerfile:
- 我们撤销了在阶段二中对
Dockerfile的修复(移除了--no-build-isolation和--hidden-import),使其与原始文件一模一样。
- 我们撤销了在阶段二中对
- 修改 Workflow (
- 结果:构建再次失败! 错误和阶段二完全相同 (
SConsnot found)。
- 结论:我们终于明白,公司原始仓库的
Dockerfile本身就存在缺陷。它无法在GitHub Actions的QEMU模拟环境中成功构建arm64。它之所以在公司内部能成功,可能是因为:- 使用了自托管的、真实的ARM64硬件作为Runner。
- 或者在某个特定的时间点,
staticx恰好有可用的预编译包。
- 最终的正确配置:
- 恢复
Dockerfile的修复:我们再次将--no-build-isolation和--hidden-import添加回Dockerfile。这两个修复是确保在任何标准CI环境中都能成功构建和运行的必要条件。 - 保持 Workflow 的精简:我们保留了只构建
arm64的配置,以满足你的最终需求。
- 恢复
| 配置差异点 | 原始 Repo | 你的 Repo (最终版) | 为什么不同? |
|---|---|---|---|
Dockerfile |
有缺陷,缺少构建参数 | ✅ 已修复 | 原始文件无法在GitHub Actions的QEMU模拟环境中构建arm64。你的版本通过添加 --no-build-isolation 和 --hidden-import 修复了构建时和运行时的错误,使其更健壮、更通用。 |
Workflow (.yml) |
深度集成Velocitas,路径复杂 | ✅ 已简化 | 你的Workflow被简化,去除了不必要的Velocitas依赖和复杂的路径,使其更独立、更易于维护,专注于核心的“构建-推送”任务。 |
| 构建目标 | 硬编码 arm64 |
硬编码 arm64 |
这一点最终保持了一致,以满足你在OWA5X设备上部署的直接需求。 |
总而言之,你的配置文件与原始仓库不同,是因为我们不仅修复了应用本身的逻辑错误,还修复了其CI/CD流程中潜藏的构建和运行时缺陷,最终形成了一套更可靠、更健壮的自动化流程。