Python: Сборка образа Docker — установка необходимых пакетов через файл requirements.txt против редактируемой установки.

Установка через requirements.txt означает использование этой команды шага сборки образа «RUN pip3 install -r requirements.txt». Редактируемая установка означает использование команды «RUN pip3 install -e .». Я столкнулся с тем, что установка через requirements.txt приводит к тому, что образы не запускаются, в то время как использование редактируемой установки приводит к тому, что образы работают, как ожидалось. Я представляю свои выводы в этом посте.

Первый учебник по Docker, который я прошел, был Learn to build and deploy your distributed applications easily to the cloud with Docker, это отличный учебник, и я успешно прошел его до конца. Затем я сделал это Build your Python image — только эту первую часть.

Что общего между ними — по моим наблюдениям:

  1. Проекты Python имеют только один файл Python. Я просмотрел некоторые другие учебники, в проектах также есть один файл Python.
  2. В файле Dockerfile они оба используют RUN pip3 install -r requirements.txt для установки необходимых пакетов.

Я хотел бы попробовать собрать образ для проекта, который имеет более одного модуля: большинство реальных проектов будут иметь более одного модуля. Код для Synology DS218: подготовка среды разработки Python 3.9 Beta compelete devepment. довольно прост, и будет хорошей первой попыткой.

Это репозиторий https://github.com/behai-nguyen/app-demo для кода. Для приведенного выше сообщения тег v1.0.0. Его можно клонировать с помощью:

git clone -b v1.0.0 https://github.com/behai-nguyen/app-demo.git
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, все сборки Docker, обсуждаемые в этом посте, были выполнены на Windows 10 Pro, с использованием docker CLI версии 20.10.12, build e91ed57.

Напомним, что схема проекта app-demo с тегом v1.0.0.0 выглядит следующим образом:

D:app_demo
|
|-- .env
|-- app.py
|-- setup.py
|
|-- src
|   |
|   |-- app_demo
|       |   
|       |-- __init__.py
|       |-- config.py
|
|-- venv
Вход в полноэкранный режим Выход из полноэкранного режима

Я создал virtualenv venv для этого проекта в Windows 10.

Сборка с помощью команды «RUN pip3 install -r requirements.txt».

Обратите внимание, что эта команда шага сборки изображения отображает setup.py, который не используется.

Сгенерируйте файл requirements.txt:

D:app_demo>venvScriptspip.exe freeze > requirements.txt
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем вручную удалите все, кроме пакетов, указанных в секции install_requires в файле setup.py.

File D:app_demorequirements.txt
Войти в полноэкранный режим Выйти из полноэкранного режима
Flask==2.1.2
python-dotenv==0.20.0
Войти в полноэкранный режим Выход из полноэкранного режима
File D:app_demoDockerfile
Войти в полноэкранный режим Выход из полноэкранного режима
# syntax=docker/dockerfile:1

FROM python:3.10.5-slim-buster

WORKDIR /app_demo

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0" ]
Войти в полноэкранный режим Выход из полноэкранного режима
File D:app_demo.dockerignore
Войти в полноэкранный режим Выход из полноэкранного режима
__pycache__
*.pyc
*.pyo
*.pyd
.Python
venv
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.mypy_cache
.pytest_cache
.hypothesis
FlaskApp.wsgi
Working
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь это корневой уровень макета проекта:

D:app_demo
|
|-- .env
|-- app.py
|-- setup.py
|-- requirements.txt 
|-- Dockerfile
|-- .dockerignore
|
...
Войти в полноэкранный режим Выйти из полноэкранного режима

Команда для сборки:

D:app_demo>docker build --tag app-demo .
Войти в полноэкранный режим Выйти из полноэкранного режима

Сборка успешно завершена. Чтобы запустить новый собранный образ:

D:app_demo>docker run --publish 8000:5000 --rm app-demo
Войти в полноэкранный режим Выйти из полноэкранного режима

Это не работает, как видно на снимке экрана ниже:

Ошибка ModuleNotFoundError: No module named ‘app_demo’.

Изменения для этой нерабочей сборки можно клонировать с помощью:

git clone -b v1.0.1 https://github.com/behai-nguyen/app-demo.git
Войти в полноэкранный режим Выйти из полноэкранного режима

✿✿✿

Поиск в Google предполагает, что другие также сталкивались с подобной ошибкой. Предлагается использовать абсолютный импорт — например, смотрите Module not found error with Python in Docker.

Я попробовал использовать абсолютный импорт, поскольку проект небольшой, изменения незначительны, и полученный образ действительно запускается. Однако это кажется неправильным… Я не должен этого делать…

Изменения для использования абсолютного импорта могут быть клонированы с помощью:

git clone -b v1.0.2 https://github.com/behai-nguyen/app-demo.git
Войти в полноэкранный режим Выйти из полноэкранного режима

В принципе, соответствующие операторы импорта в:

File D:app_demoapp.py
File D:app_demosrcapp_demo__init__.py
Enter fullscreen mode Выйти из полноэкранного режима

были снабжены префиксом src., чтобы стать соответственно:

from src.app_demo import create_app
from src.app_demo.config import get_config
Ввести полноэкранный режим Выйти из полноэкранного режима

Сборка и запуск, соответственно, с:

D:app_demo>docker build --tag app-demo .
D:app_demo>docker run --publish 8000:5000 --rm app-demo
Ввести полноэкранный режим Выйти из полноэкранного режима

Запуск прошел успешно. http://localhost:8000 отображает ожидаемый вывод Hello, World!

Сборка с помощью команды «RUN pip3 install -e .».

Обратите внимание на этот шаг сборки образа:

❶ Оба:

File D:app_demoapp.py
File D:app_demosrcapp_demo__init__.py
Войти в полноэкранный режим Выход из полноэкранного режима

операторы импорта возвращаются к относительному импорту:

from app_demo import create_app
from app_demo.config import get_config
Войти в полноэкранный режим Выйти из полноэкранного режима

То есть префикс src., добавленный в последней сборке, был удален.

❷ Эта команда шага сборки образа делает файл requirements.txt устаревшим.

✿✿✿

Я делал еще один образ Docker для другого проекта Python, и подумал, что вместо этого попробую установить редактируемый образ RUN pip3 install -e . Я подумал, что мне все равно придется изменить исходные коды для абсолютного импорта, так почему бы просто не использовать setup.py, который уже есть. Сборка прошла без проблем. Я запустил ее, чтобы получить первый сбой импорта… Не сбой!

Он работает! Я до сих пор не знаю, почему он работает!

Поэтому я возвращаюсь к этому проекту, и отсюда этот пост. Изменения следующие:

File D:app_demoDockerfile
Вход в полноэкранный режим Выход из полноэкранного режима
# syntax=docker/dockerfile:1

FROM python:3.10.5-slim-buster

WORKDIR /app_demo

COPY . .

RUN /usr/local/bin/python -m pip install --upgrade pip && 
    pip3 install -e .

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0" ]
Войти в полноэкранный режим Выход из полноэкранного режима

requirements.txt устарел; он добавлен в D:app_demo.dockerignore.

File D:app_demo.dockerignore
Войти в полноэкранный режим Выход из полноэкранного режима
... 
requirements.txt
Войти в полноэкранный режим Выход из полноэкранного режима

Клонируйте новые изменения с помощью следующей команды, пожалуйста, выбросьте файл requirements.txt:

git clone -b v1.0.3 https://github.com/behai-nguyen/app-demo.git
Войти в полноэкранный режим Выйти из полноэкранного режима

Соберите и запустите, соответственно, с помощью:

D:app_demo>docker build --tag app-demo .
D:app_demo>docker run --publish 8000:5000 --rm app-demo
Войти в полноэкранный режим Выйти из полноэкранного режима

Запуск проходит успешно:

http://localhost:8000 отображает ожидаемый вывод Hello, World!

✿✿✿

Я не знаю, почему RUN pip3 install -e . работает… Пожалуйста, скажите мне, если вы знаете, я буду вам очень признателен.

С тех пор, как я принял решение использовать setup.py, этот шаг сборки образа Docker просто отлично работает. Я доволен. Спасибо, что прочитали, и я надеюсь, что вы найдете этот пост полезным.

Оцените статью
devanswers.ru
Добавить комментарий