#python #docker #docker-compose #dockerfile
#python #docker #docker-compose #dockerfile
Вопрос:
Я пытаюсь развернуть приложение Python в качестве контейнера Docker, используя Dockerfile и docker-compose.
Структура проекта такова:
ms-request
- src
__init__.py
- exceptions
__init__.py
ms_request_exceptions.py
- messaging
__init__.py
receive_rabbit.py
send_rabbit.py
- request
__init__.py
bsrequest.py
- test
__init__.py
test_bsrequest.py
Dockerfile
requirements.txt
В моем receive_rabbit.py
скрипте я импортирую функции из пакетов запросов и сообщений следующим образом:
from src.request import bsrequest
from src.messaging.send_rabbit import send_message
Выполнение этого с помощью PyCharm работает нормально. Запуск его из командной строки изначально не работал, пока я не обновил PYTHONPATH с помощью export PYTHONPATH=${PYTHONPATH}:.
.
Я хотел бы развернуть это как контейнер Docker, поэтому я создал Dockerfile и запись в моем docker-compose.yml для проекта.
Dockerfile:
FROM python:3
WORKDIR /bsreq
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src
COPY test/ ./test
RUN export PYTHONPATH=${PYTHONPATH}:.
CMD [ "python", "/bsreq/src/messaging/receive_rabbit.py" ]
docker-compose.yml:
version: "3.3"
services:
rabbitmq: [...]
bs-request:
build: ./ms-request/
depends_on:
- rabbitmq
env_file:
- rabbit.env
[...]
Запуск этого использования docker-compose up bs-request
всегда заканчивается сбоем с ошибкой No module named 'src'
.
Я пробовал несколько вариантов ввода для строк WORKDIR, COPY, PYTHONPATH и CMD в Dockerfile. Все это приводит к одной и той же ошибке. Я пробовал относительный импорт, который выдает Attempted relative import with no known parent package
.
Я надеюсь, что это проблема, с которой другие сталкивались раньше. Что мне нужно сделать, чтобы это развертывание заработало?
Ответ №1:
docker layers-способ построения образа делает export
его непригодным для использования сразу после соответствующей RUN
команды.
FROM python:3
WORKDIR /bsreq
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src
COPY test/ ./test
RUN export PYTHONPATH=${PYTHONPATH}:. #--> exporting
CMD [ "python", "/bsreq/src/messaging/receive_rabbit.py" ] #--> last export is not persistent
в качестве обходного пути вы устанавливаете переменные среды, которые будут сохраняться при сборке И в конечном образе с ENV PYTHONPATH=${PYTHONPATH}:.
помощью command .
дополнительное чтение: https://vsupalov.com/docker-build-time-env-values /
в любом случае, предлагаемый метод заключается в записи setup.py
файла и установке вашего пакета, python setup.py install
чтобы он был установлен как пакет, и импорт будет работать.
P.S лучшим, более обновленным способом было бы использовать такие инструменты, poetry
которые используют pyproject.toml
(согласно PEP 518, 517), которые являются будущим способом python!
бонусное чтение: https://python-poetry.org /
удачи!
Комментарии:
1. Большое вам спасибо! Это почти как три ответа в одном. Я буду обновлять проект, чтобы использовать Poetry!