我使用fastapi、docker、docker-compose、kafka。 我尝试启动 modules-consumer:
docker-compose up consumer-modules
但是我收到了ModuleNotFoundError:
ModuleNotFoundError: No module named 'core'
导入modules_consumer.py:
from core import settings
where
core
- 项目文件夹,而不是库。
Dockerfile:
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app
RUN rm -rf .venv/
RUN apt-get update && \
apt-get install -y locales \
python-dev-is-python3 libldap2-dev libsasl2-dev libssl-dev \
libmagic1 && \
echo ru_RU.UTF-8 UTF-8 >> /etc/locale.gen && \
locale-gen && \
python -m pip install --upgrade pip && \
python -m pip install poetry
RUN poetry config virtualenvs.create false && poetry install --no-root --no-dev
EXPOSE 80
消费者模块在docker-compose.yaml:
consumer-modules:
build:
context: ../app
volumes:
- ../app:/app
depends_on:
- db
command: sh -c "python3 consumers/modules_consumer.py"
项目结构:
app/
├─ consumers/
│ ├─ modules_consumer.py
│ ├─ __init__.py
├─ core/
│ ├─ settings.py
│ ├─ __init__.py
├─ Dockerfile
├─ docker-compose.yaml
我在 stackoverflow 上发现了类似的问题,但他们没有帮助我。
可能是什么问题?
这是一个路径问题。最好通过修改
$PYTHONPATH
环境变量来解决这个问题,该变量告诉 Python 进程在哪里可以找到它需要的文件。
你已经解释了目录结构是
/app
├─ core/
│ ├─ settings.py
├─ consumers/
│ ├─ modules_consumer.py
当您运行
docker compose up
时,consumer-modules
服务将配置为运行命令 python3 consumers/modules_consumer.py
。它在 /app
的容器内运行。
现在发生的事情是这样的:
modules_consumer.py
中的代码从文件所在的子目录执行。如果它位于 /app/modules_consumer.py
,那么它包含的代码 - from core import settings
- 将运行得很好。 Python 进程将在所有直接子目录(core/
和 consumers/
)中查找 settings.py
,并在 core/
中找到它。
相比之下,因为
modules_consumer.py
在 consumers/
中,所以这不可能发生(没有帮助)。在 core.py
中找不到名为 consumers/
的文件后,Python 进程将在 consumers/
中查找任何子目录,但找不到任何子目录。
解决这个问题的方法是将
/app
添加到$PYTHONPATH
环境变量中。这样,Python 进程就会知道 - 以及 当前目录 - 它应该在 /app
中查找导入。我认为在你的情况下,最简单的事情就是在你的
docker-compose.yml
中覆盖这个变量:
consumer-modules:
build:
context: ../app
volumes:
- ../app:/app
depends_on:
- db
environment:
- PYTHONPATH="/app"
command: sh -c "python3 consumers/modules_consumer.py"
(如果结果变得更复杂,例如,因为这会覆盖默认情况下已经在$PYTHONPATH
中的一些需要的东西,有许多替代方法来设置和/或扩展此环境变量)