Как сохранить согласованность зависимостей между средой разработки и производственной среды для пакета Python с поэзией и pyproject.toml

У меня есть пакет python, в котором зависимости указаны в файле pory.lock для разработки и тестирования. Затем я создаю и публикую пакет, который устанавливается в производственном образе докера. Но вот проблема: опубликованный пакет его зависимость , указанная в tool.poetry.dependencies части pyproject.toml, которая может отличаться от poetry.lock. Так что вполне возможно, что производственный env окажется с зависимостями, отличными от тестового env.

Я могу придумать несколько способов добиться согласованности, но ни один из них мне не кажется подходящим:

  1. Используйте те же установленные версии в pyproject.toml, что и в pory.lock. Это гарантирует, что опубликованный пакет будет иметь те же зависимости, что и dev / test. Но какой вообще смысл хранить файл pory.lock на этом этапе, поскольку pyproject.toml также можно использовать, если нет файла pory.lock. Я думаю, что это работает, но тогда я вообще не понимаю, зачем вообще есть поэзия.

  2. В производственном образе докера извлеките файл pory.lock из репозитория пакета и запустите poetry installперед установкой самого пакета. Но это увеличит размер образа докера, внесет ненужную конфигурацию, если репо является частным, и в целом не кажется естественным.

Я новичок в этой части Python, поэтому, возможно, один из них - «стандартный» рабочий процесс. А может я просто чего-то совсем упускаю. Спасибо за ответы!

1 ответ

Решение

Вариант 1. Уточнение версий зависимостей, как вы описываете в варианте 1, не рекомендуется, поскольку это приводит к излишне строгому пакету. Это часто приводит к конфликтам, которых можно избежать, особенно если пакет, который вы пишете, также является внутренней зависимостью от других проектов.

Вариант 2 : обработка подобных зависимостей определенно лучше, чем вариант 1, но сложнее поддерживать, чем вариант, который я хочу предложить. В качестве примечания, для этого также требуется, чтобы поэзия была установлена ​​на вашем образе докера - вам действительно нужно если все, что вы хотите сделать, это установить пакеты.

Вариант 3. Создайте рулевую рубку в начале конвейера сборки и используйте ее на последующих этапах для установки зависимостей среды выполнения. Это гарантирует, что нет возможных расхождений между протестированным кодом и развернутым кодом, и это действительно быстро, потому что нет загрузки из Интернета или создания дистрибутивов только с исходным кодом. Я воспользуюсь образцом чтобы показать, что я имею в виду, но концепция должна без особых проблем транслироваться в любой другой CI / CD:

.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/*

Предостережения

Изображение, которое вы используете для задание должно быть той же аркой, что и базовый образ в вашем файле докера (или любое задание, которое пытается установить рулевую рубку или повторно использовать виртуальную среду) - если вы используете debian для своих заданий gitlab, но alpine в prod-образе, все развалится очень быстро.

Это также распространяется на создание образа локально, если это то, что вы хотите сделать во время разработки. Если ваша рабочая станция имеет другую архитектуру, например ubuntu, возможно, вы больше не сможете этого сделать. Вот рецепт сценария, который создает для вас рабочую рубку на основе Debian.

Другие вопросы по тегам