Docker运行Python应用遭遇importlib.metadata.PackageNotFoundError问题
问题描述
项目Docker目录结构
.../ docker/ src/ my_app/ __init__.py # 其余Python文件 my_app_entrypoint.py Pipfile Pipfile.lock pyproject.toml setup.cfg setup.py test/ build.yaml Dockerfile ...
Dockerfile关键片段
COPY src/Pipfile* /home/workspace/ RUN pip install --upgrade pip \ && pip install pipenv \ && pipenv requirements > requirements.txt \ && pip install -r requirements.txt ... COPY src/pyproject.toml ./ COPY src/setup.cfg ./ COPY src/setup.py ./ COPY src/my_app_entrypoint.py ./ COPY src/my_app ./my_app RUN chmod a+x my_app_entrypoint.py ...
运行错误信息
Traceback (most recent call last): File "/home/workspace/my_app_entrypoint.py", line 2, in <module> import my_app File "/home/workspace/my_app/__init__.py", line 20, in <module> __version__ = metadata.version("my_app") File "/usr/local/lib/python3.9/importlib/metadata.py", line 569, in version return distribution(distribution_name).version File "/usr/local/lib/python3.9/importlib/metadata.py", line 542, in distribution return Distribution.from_name(distribution_name) File "/usr/local/lib/python3.9/importlib/metadata.py", line 196, in from_name raise PackageNotFoundError(name) importlib.metadata.PackageNotFoundError: my_app
触发错误的代码:
# /home/workspace/my_app/__init__.py __version__ = metadata.version("my_app")
setup.cfg配置片段
[metadata] name = my_app version = 1.0.0 ... [options] packages = my_app
用户疑问:已尝试多种方法,但构建镜像后仍出现相同错误,似乎程序无法识别该包或setuptools未正确加载。是否遗漏了步骤?是否需要在Dockerfile中添加RUN pip install .命令来安装该包?
解决方案
是的,你确实需要在Dockerfile中添加RUN pip install .命令,原因如下:
importlib.metadata.version("my_app")是从Python的已安装包元数据中读取版本,而非直接读取本地的setup.cfg。当前仅将源码文件复制到工作目录,并未将my_app作为正式Python包安装到环境中,因此Python无法找到对应的包元数据,抛出PackageNotFoundError。正确操作是在复制完所有setup相关文件和源码后,执行安装命令:
修改Dockerfile,在复制文件的步骤后新增:
# 安装my_app包到Python环境 RUN pip install .
完整的相关步骤示例:
COPY src/Pipfile* /home/workspace/ RUN pip install --upgrade pip \ && pip install pipenv \ && pipenv requirements > requirements.txt \ && pip install -r requirements.txt COPY src/pyproject.toml ./ COPY src/setup.cfg ./ COPY src/setup.py ./ COPY src/my_app_entrypoint.py ./ COPY src/my_app ./my_app RUN chmod a+x my_app_entrypoint.py # 新增安装包的步骤 RUN pip install .
执行此操作后,my_app会被正式安装到Python环境中,importlib.metadata就能找到对应的包元数据,读取版本信息时不再报错。
另外,也可使用pip install -e .进行开发模式安装,但生产镜像中推荐使用常规的pip install .,确保包被正确安装并优化。
内容的提问来源于stack exchange,提问作者P. Solar
相关产品推荐
相关产品推荐

