GitLab CI/CD遇ModuleNotFoundError:无法找到Submodule1.Submodule2.filename
解决GitLab CI/CD中Python子模块ModuleNotFoundError问题
问题分析
你遇到的ModuleNotFoundError: No module named 'Submodule1.Submodule2.filename'错误,核心原因可能是子模块未正确拉取、Docker构建时未包含子模块内容,或者Python路径未配置正确。结合你的配置,以下是针对性的解决方案:
1. 确认CI环境中子模块的拉取状态
首先排查子模块是否真的被拉取到CI工作目录:
- 在
before_script中添加目录检查命令,验证文件存在性:before_script: - apk update && apk add git - git submodule update --init --recursive - # 新增:检查子模块目录结构 - ls -la Submodule1/ - ls -la Submodule1/Submodule2/
如果输出中没有Submodule2的文件,说明子模块拉取失败,重点排查SSH权限:
- 由于
.gitmodules使用了SSH路径,需确保GitLab CI Runner拥有访问子模块仓库的权限:- 在主项目和所有子模块仓库的设置 > 仓库 > 部署密钥中,添加同一对SSH密钥(公钥存入仓库,私钥配置到CI Runner或通过GitLab项目变量加载)。
2. 修复.gitmodules的嵌套子模块配置
当前主仓库直接配置Submodule1/Submodule2作为子模块,容易导致递归拉取逻辑混乱,建议调整为:
- 主仓库仅保留
Submodule1的子模块配置:[submodule "Submodule1"] path = Submodule1 url =../../...git - 进入本地
Submodule1仓库目录,执行git submodule add <Submodule2的SSH路径> Submodule2,将Submodule2作为Submodule1的子模块提交到Submodule1仓库。 - 主仓库更新Submodule1引用:
git submodule update --remote Submodule1,提交主仓库变更后,GitLab CI启用递归拉取时会自动获取Submodule1及其内部的Submodule2。
3. 确保Docker构建时包含子模块内容
如果子模块已拉取到CI环境,但Docker镜像中没有,检查以下两点:
- 查看
.dockerignore文件,确保未排除Submodule1或Submodule1/Submodule2目录。 - 确认Dockerfile中的
COPY命令包含子模块目录,比如用COPY . .将整个项目目录复制到容器(需保证工作目录设置正确)。
4. 配置Python模块搜索路径
若子模块已存在于容器中,但Python仍找不到模块,需将Submodule1添加到Python搜索路径:
- Django项目:在
settings.py中添加:import sys from pathlib import Path # 将Submodule1目录加入Python路径 sys.path.append(str(Path(BASE_DIR) / "Submodule1")) - 通用Python项目:在Dockerfile中设置环境变量:
其中ENV PYTHONPATH="/app/Submodule1:$PYTHONPATH"/app为容器中项目的工作目录,需根据实际情况调整。
5. 优化GitLab CI子模块拉取配置
建议使用GitLab CI内置的子模块策略,比手动执行命令更可靠:
- 启用
GIT_SUBMODULE_STRATEGY: recursive变量,移除手动的git submodule update命令:variables: GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_UPDATE_FLAGS: --jobs 4 CI_DEBUG_TRACE: "true" POSTGRES_HOST_AUTH_METHOD: trust build-run: stage: build before_script: - apk update && apk add git # 移除手动的git submodule update命令
内容的提问来源于stack exchange,提问作者L. T
相关产品推荐
相关产品推荐

