Как сохранить согласованность зависимостей между средой разработки и производственной среды для пакета Python с поэзией и pyproject.toml
У меня есть пакет python, в котором зависимости указаны в файле pory.lock для разработки и тестирования. Затем я создаю и публикую пакет, который устанавливается в производственном образе докера. Но вот проблема: опубликованный пакет его зависимость , указанная в tool.poetry.dependencies части pyproject.toml, которая может отличаться от poetry.lock. Так что вполне возможно, что производственный env окажется с зависимостями, отличными от тестового env.
Я могу придумать несколько способов добиться согласованности, но ни один из них мне не кажется подходящим:
Используйте те же установленные версии в pyproject.toml, что и в pory.lock. Это гарантирует, что опубликованный пакет будет иметь те же зависимости, что и dev / test. Но какой вообще смысл хранить файл pory.lock на этом этапе, поскольку pyproject.toml также можно использовать, если нет файла pory.lock. Я думаю, что это работает, но тогда я вообще не понимаю, зачем вообще есть поэзия.
В производственном образе докера извлеките файл pory.lock из репозитория пакета и запустите
poetry install
перед установкой самого пакета. Но это увеличит размер образа докера, внесет ненужную конфигурацию, если репо является частным, и в целом не кажется естественным.
Я новичок в этой части Python, поэтому, возможно, один из них - «стандартный» рабочий процесс. А может я просто чего-то совсем упускаю. Спасибо за ответы!
1 ответ
Вариант 1. Уточнение версий зависимостей, как вы описываете в варианте 1, не рекомендуется, поскольку это приводит к излишне строгому пакету. Это часто приводит к конфликтам, которых можно избежать, особенно если пакет, который вы пишете, также является внутренней зависимостью от других проектов.
Вариант 2 : обработка подобных зависимостей определенно лучше, чем вариант 1, но сложнее поддерживать, чем вариант, который я хочу предложить. В качестве примечания, для этого также требуется, чтобы поэзия была установлена на вашем образе докера - вам действительно нужно
Вариант 3. Создайте рулевую рубку в начале конвейера сборки и используйте ее на последующих этапах для установки зависимостей среды выполнения. Это гарантирует, что нет возможных расхождений между протестированным кодом и развернутым кодом, и это действительно быстро, потому что нет загрузки из Интернета или создания дистрибутивов только с исходным кодом. Я воспользуюсь образцом
.gitlab-ci.yml
image: resero/python-poetry
# I just maintain my own python:slim + poetry image, this public one serves as an example
stages:
- build
- test
- release
variables:
WHEELHOUSE: wheelhouse
POETRY_VIRTUALENVS_PATH: venv # speeds up jobs
IMAGE_NAME: my-app
wheels:
stage: build
script:
- poetry install
- poetry build -f wheel
- poetry export -f requirements.txt -o requirements.txt
- poetry run pip wheel -w ${WHEELHOUSE} -r requirements.txt
- mv dist/* ${WHEELHOUSE}
artifacts:
expire_in: 1 week
paths:
- ${WHEELHOUSE}
- ${POETRY_VIRTUALENVS_PATH}
pytest:
stage: test
script:
# no need to run `poetry install` because the venv from the build-job gets re-used
- poetry run pytest
dockerize:
stage: release
image: docker:git
script:
- docker build . -t ${IMAGE_NAME}
- docker push ${IMAGE_NAME}
Если у вас есть такая рулевая рубка, доступная во время докеризации, самого Dockerfile часто бывает достаточно, как это, плюс правильная точка входа для вашего приложения:
Dockerfile
FROM python:3.8-slim
COPY wheelhouse/* wheelhouse/
RUN pip install wheelhouse/*
Предостережения
Изображение, которое вы используете для
Это также распространяется на создание образа локально, если это то, что вы хотите сделать во время разработки. Если ваша рабочая станция имеет другую архитектуру, например ubuntu, возможно, вы больше не сможете этого сделать. Вот рецепт сценария, который создает для вас рабочую рубку на основе Debian.