如何修复Python Docker容器中'app'模块的ModuleNotFoundError问题
问题描述
使用以下Dockerfile构建并运行Python容器时,出现模块导入错误:
# 使用官方Python运行时作为基础镜像 FROM python:3.10.5 # 设置容器内的工作目录 WORKDIR /code/ RUN pip install pipenv COPY Pipfile Pipfile.lock /code/ RUN pipenv install --system --dev # 安装Google Chrome依赖 RUN apt-get update && apt-get install -y \ # 大量依赖 && rm -rf /var/lib/apt/lists/* # 安装Google Chrome RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb RUN dpkg -i google-chrome-stable_current_amd64.deb RUN apt --fix-broken install -y # 下载并安装最新稳定版ChromeDriver RUN CHROME_DRIVER_VERSION=$(curl --silent https://chromedriver.storage.googleapis.com/LATEST_RELEASE) && \ wget https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip && \ unzip chromedriver_linux64.zip && \ rm chromedriver_linux64.zip && \ mv chromedriver /usr/local/bin/ COPY . /code/ # 运行main_daily_task.py文件 CMD ["python", "app/main_daily_task.py"]
运行时错误信息:
2023-05-25 16:27:46 Traceback (most recent call last):
2023-05-25 16:27:46 File "/code/app/main_daily_task.py", line 13, in
2023-05-25 16:27:46 from app.database import SessionLocal
2023-05-25 16:27:46 ModuleNotFoundError: No module named 'app'
将导入语句改为from database import SessionLocal可正常运行,但因代码需在其他容器复用,无法修改导入路径,且不想通过运行时指定base_dir解决,需要合理修复方案。
问题根源
当执行python app/main_daily_task.py时,Python会将**脚本所在的目录(/code/app)**添加到模块搜索路径sys.path中,而非工作目录/code。因此import app.database无法找到顶层包app,而import database能生效是因为database.py位于/code/app目录下。
修复方案
方案1:以模块方式运行脚本
- 确保
/code/app目录下存在空的__init__.py文件(若不存在则创建),使app成为标准Python包。 - 修改Dockerfile中的CMD指令为:
CMD ["python", "-m", "app.main_daily_task"]-m参数会将当前工作目录(/code)添加到sys.path,Python即可识别app作为顶层包,从而正常解析from app.database import SessionLocal。
方案2:设置PYTHONPATH环境变量
在Dockerfile中WORKDIR /code/之后添加环境变量配置,将/code加入Python的模块搜索路径:
WORKDIR /code/ ENV PYTHONPATH=/code
此配置会让Python始终在/code目录下查找包,无需修改脚本或添加额外文件,即可满足原有导入路径的要求。
内容的提问来源于stack exchange,提问作者DMX

