Docker容器中本地Python模块导入报错的问题排查与解决
嘿,我来帮你搞定这个Docker里Python模块导入的坑!
你遇到的ModuleNotFoundError核心原因是:Python的模块搜索路径没包含你的app目录,虽然你用COPY把app文件夹复制到了容器里,但运行时Python不知道要去/app目录找模块,自然就找不到同目录下的wekinator.py了。
下面给你两个最靠谱的解决方案:
方案1:设置工作目录(最推荐,简单直接)
修改你的Dockerfile,添加WORKDIR指令让容器默认工作在/app目录下,这样Python会自动把当前工作目录加入模块搜索路径,导入就能正常工作了。
修改后的Dockerfile:
FROM python:3.7 RUN pip install fastapi uvicorn python-osc EXPOSE 80 WORKDIR /app # 新增这行,把工作目录切换到/app COPY ./app . # 简化复制命令,把本地app里的内容复制到当前工作目录(/app) CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] # 直接运行main:app,不用加app前缀
这样调整后,容器启动后会在/app目录下运行uvicorn,Python能直接找到main.py,而main.py里的import wekinator也能找到同目录的wekinator.py。
方案2:把app转为Python包,用相对导入
如果你不想修改工作目录,也可以通过把app变成Python包来解决:
- 在本地的
app文件夹里创建一个空的__init__.py文件,让Python把app识别为一个合法的包:
. ├── Dockerfile ├── README.md └── app ├── __init__.py # 新增这个空文件 ├── main.py └── wekinator.py
- 修改
main.py里的导入语句,使用相对导入:
# 把原来的import wekinator改成 from . import wekinator
- 你的原Dockerfile可以保持不变,因为uvicorn是通过
app.main:app来导入包的,这时候相对导入能正确定位到同包下的wekinator模块。
为啥原来的COPY命令没起作用?
你原来的COPY ./app /app确实把整个app文件夹复制到了容器的/app目录,目录结构是对的,但问题出在Python的默认搜索路径不包含/app——容器默认的工作目录是/,Python只会在当前工作目录和site-packages里找模块,所以main.py运行时找不到wekinator.py。
内容的提问来源于stack exchange,提问作者msalla
相关产品推荐
相关产品推荐

