我正在尝试将我的程序容器化。本地一切工作正常,但当我构建和运行容器时,导入无法按我希望的方式工作。
这是我的 Dockerfile
FROM python:3.8
WORKDIR /src
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
CMD ["python3", "./app/run.py"]
这是我的一般文件结构。
app
├── module
│ ├── file.py
│ └── __init__.py
├── __init__.py
└── run.py
run.py 看起来像这样:
from app.module import Class
instance = Class(args)
instance.do_stuff
我的应用程序/模块/init.py有:
from .file import Class
再次,当我在本地运行它时,效果很好。然而,当我在 docker 中运行它时,我最终遇到了导入错误。
Traceback (most recent call last):
File "./app/run.py", line 3, in <module>
from app.module import Class
ModuleNotFoundError: No module named 'app'
我可以通过将 run.py 中的导入更改为
from module import Class
而不是 from app.module import Class
来让我的代码在容器中运行。不过我想更好地理解它。老实说,我更喜欢我的导入是 app.module,以使本地导入更加明显。
您遇到的问题似乎与 Python 如何解析 Docker 容器中的模块导入有关。当您在
from app.module import Class
文件中执行 run.py
时,Python 期望在容器中找到名为 app 的模块,但事实并非如此。
要解决此问题,同时仍将导入保留为
from app.module import Class
,您需要确保应用程序目录被视为包。您可以通过在应用程序目录中添加 empty __init__.py
文件来实现此目的。这告诉 Python app 是一个 package 并允许您使用像 from app.module import Class
这样的绝对导入。
以下是更新后的目录结构:
app
├── __init__.py <--- Add this file
├── module
│ ├── __init__.py
│ ├── file.py
└── run.py