Какой рекомендованный способ установки зависимостей Python в контейнерах Ubuntu 24.04?

Вопрос или проблема

Мы начали переносить наши docker-контейнеры на версию 24.04 и получили следующую рекомендацию от ОС во время установки python-зависимостей:

root@76ea3b9e695a:/# pip install numpy
error: externally-managed-environment

× Это среда с внешним управлением
╰─> Чтобы установить пакеты Python на уровне системы, попробуйте apt install
python3-xyz, где xyz — это пакет, который вы пытаетесь
установить.

Если вы хотите установить пакет Python, не входящий в состав Debian,
создайте виртуальную среду, используя python3 -m venv path/to/venv.
Затем используйте path/to/venv/bin/python и path/to/venv/bin/pip. Убедитесь, что у вас установлен python3-full.

Если вы хотите установить приложение Python, не входящее в состав Debian,
может быть проще использовать pipx install xyz, который будет управлять
виртуальной средой для вас. Убедитесь, что у вас установлен pipx.

См. /usr/share/doc/python3.12/README.venv для получения дополнительной информации.

Примечание: Если вы считаете, что это ошибка, пожалуйста, обратитесь к вашей установки Python или к поставщику дистрибутива ОС.
Вы можете переопределить это, рискуя нарушить установку Python
или ОС, передав --break-system-packages.
Подсказка: См. PEP 668 для детальной спецификации.

Вопросы:

  1. Предполагая, что python-* не покрывают все наши зависимости, действительно ли подход с venv является рекомендованным способом установки python-зависимостей в контейнерах 24.04 для предоставления приложения с единой точкой входа, например, __main__.py?
  2. Каковы преимущества использования python-* в качестве зависимостей? Обеспечивается ли поддержка уязвимостей Ubuntu для них?

Вкратце: используйте venv для проектов (и используйте инструмент для управления и разрешения ваших зависимостей)

Я уверен, что существует несколько способов сделать это, но вот мое мнение:

  1. Да, установка в venv действительно предпочтительна, и вот почему:

    • Устанавливая некоторые пакеты с помощью pip, а другие с помощью apt, у вас возникнут трудности с управлением детерминированными сборками/зависимостями. Apt и/или pip могут модифицировать или удалять пакеты, установленные другой системой, и могут мешать работе друг с другом.
    • Apt может обновлять свои версии пакетов, которые могут оказаться несовместимыми с другими зависимостями, установленными вами с помощью pip (что вам придется сделать, так как не все пакеты Python доступны через apt), что может нарушить работу вашего приложения в будущем.
    • Установка пакетов pip в ОС может нарушить работу других систем ОС, которые зависят от правильных пакетов python-*, установленных через apt (которые могут быть модифицированы pip).
    • Сборка в venv позволяет копировать среду при использовании многоэтапного Dockerfile для уменьшения размера окончательного изображения (см. пример ниже).
    • Наконец, управление всеми зависимостями с помощью одной системы в venv позволяет лучше контролировать сборки с инструментами, поддерживающими файлы блокировок, такими как uv или poetry.
  2. Пакеты apt python-* в основном предназначены для систем ОС, которые зависят от них. Системы ОС разработаны и протестированы с учетом данных зависимостей и хорошо работают вместе. Пока вы используете только эти зависимости, они, вероятно, будут хорошо взаимодействовать друг с другом. Эти пакеты иногда обновляются, но, вероятно, не будут содержать каждый новый выпуск, так как это потребовало бы слишком много тестирования, чтобы убедиться, что все системы ОС продолжают работать.
    Конечно, исправления безопасности для этих пакетов, вероятно, предоставляются обслуживающими их apt пакетчиками, но, опять же, обновления могут быть не такими частыми или быстрыми.


Пример

Пример того, как построить детерминированную Docker сборку с использованием инструмента uv, можно найти здесь. Мне особенно нравится эта многоэтапная Docker сборка, потому что в работающем контейнере uv не требуется, так как туда копируется только venv. (Обратите внимание, что в данном примере на самом деле используется системный интерпретатор в обеих образах, так что все еще присутствует системная зависимость.)


Мнение

В общем, управление зависимостями становится намного проще с хорошим инструментом. Uv — это новейший инструмент в сообществе Python, и я использую его для большинства своих новых проектов. Поскольку он является целенаправленным и работает только с venv, вышеуказанный рабочий процесс становится практически обязательным при работе с ним.

Если у вас есть только несколько требований для простого скрипта, то, возможно, будет достаточно установить их напрямую без venv, просто такие проекты имеют тенденцию разрастаться и становиться более сложными со временем. Так что да, делайте правильно с первого раза 😉

.

Ответ или решение

Теория

С переходом на версию Ubuntu 24.04, ваша команда столкнулась с рекомендацией использовать виртуальные окружения для установки зависимостей Python. Это связано с концепцией внешне управляемых окружений, которая обеспечивает более надежное управление зависимостями и минимизирует конфликты версий библиотек. Зависимости, управляемые системно (например, через apt в Ubuntu), могут поддерживать стабильность и согласованность пакетов, но не всегда могут удовлетворить все специфичные потребности вашего приложения, особенно если оно зависит от более свежих версий библиотек или специальных пакетов, еще не включенных в репозитории APT.

Использование виртуальных окружений, созданных через python3 -m venv, обеспечивает изолированное пространство для установки всех необходимых зависимостей, что позволяет избежать конфликтов с системными пакетами и облегчает переносимость приложения в различные среды.

Пример

Рассмотрим сценарий использования виртуального окружения для вашего контейнера в Ubuntu 24.04. При создании контейнера вы можете воспользоваться следующим примером Dockerfile:

# Выбор базового образа
FROM ubuntu:24.04

# Установка Python и необходимых инструментов
RUN apt update && apt install -y python3 python3-venv python3-pip

# Создание и активация виртуального окружения
WORKDIR /app
RUN python3 -m venv venv

# Активация окружения и установка зависимостей
COPY requirements.txt .
RUN ./venv/bin/pip install -r requirements.txt

# Копирование и запуск приложения
COPY . .
CMD ["./venv/bin/python", "-m", "myapp"]

В этом примере показан процесс установки Python и его использования для создания виртуального окружения и последующего управления зависимостями через pip.

Применение

Применение метода использования venv дает следующие преимущества:

  1. Изоляция окружения: Все зависимости находятся в одном месте, что предотвращает конфликты с системными пакетами.
  2. Контроль версий: Вы можете четко управлять версиями используемых библиотек и создавать замороженные файлы зависимостей (requirements.txt), что обеспечивает повторяемость сборок.
  3. Снижение зависимости от системы: Ваше приложение становится независимым от изменений системных пакетов, что упрощает обновление операционной системы и других компонентов.
  4. Снижение проблем с безопасностью: Обновления зависимостей могут управляться вами, что позволяет оперативно реагировать на уязвимости, пока системные пакеты могут задерживать эти обновления.

Использование системных пакетов (например, python-* из APT) полезно для обеспечения совместимости с другими системными компонентами, однако для проекта, где важна гибкость версий и контроль безопасности, пакетный менеджмент через venv и pip может быть более актуален.

Заключение

Переход на использование виртуальных окружений в контейнерах Ubuntu 24.04 оправдан для проектов, где требуется единая точка входа и хорошее управление зависимостями. Это улучшит стабильность и управляемость ваших приложений, упростит процесс обновления и минимизирует проблемы, связанные с несовместимостью пакетов. Adopting this method can enhance your development practices, offering more consistent and maintainable application environments.

Оцените материал
Добавить комментарий

Капча загружается...