Действительно минимальные образы встречаются крайне редко и стоят дорого. Если вы не уверены, что у вас именно такой образ, и не готовы поддерживать его в таком состоянии на протяжении всего проекта, независимо от того, кто будет над ним работать, лучше даже не пытаться.
Стремиться к лучшему? Нет. Да и в чем сложность постараться создать минимальный образ для python? Это делается один раз на проект, да и во многих схожих проектах Dockerfile практически одинаковый, никаких трудностей там нет. Куча информации на хабре как создать минимальный и правильный Dockerfile.
С учётом того, что контейнер по своей природе служит для изоляции, может показаться нелогичным добавлять ещё один слой изоляции поверх этого.
Именно так!
venv — это обеспечение однородности: где бы вы ни находились, вы используете venv. Это избавляет вас от необходимости разбираться с вариациями и сложностями, которые они создают.
Контейнер и так обеспечивает однородность, причем чистую, а не то что у вас может быть на рабочем компьютере, даже с venv.
А если вы начнёте устанавливать пакеты через pip без venv, рано или поздно что-то из Pypi и что-то из операционной системы столкнутся.
Образ контейнера для python имеет много разных версий: alpine, slim, bookworm, и т.д. Всегда при сборке контейнера нужно выбирать, какой базовый образ выбрать для проекта. Затем устанавливаются дополнительные библиотеки и потом уже python зависимости. Если что-то когда-то сломается, то это знак, что нужно исправить ошибку в образе контейнера, а не брать самый тяжелый python:latest и добавлять к нему виртуальное окружение отдельной папкой и смотреть на образ в 2 ГБ.
Не говоря уже о том, сколько ресурсов вы готовы потратить на поддержание этого прекрасного чистого состояния установки без venv? На документацию? Обучение? Процессы?
Очень мало по сравнению с необразованностью и попыткой сделать как легче, а не как лучше. Мы же технически грамотные люди, нужно разбираться в том что делаем, тем более это в разы проще написания проекта.
И ради чего? Какая цель? Если вы не можете ответить на этот вопрос мгновенно, просто используйте venv.
Цель обеспечить минимум лишнего окружения для проекта и его прозрачного использования в чистой среде контейнера с конкретными зависимостями. Если это не требуется, то может и docker вовсе лишний. Можно запускать очень хорошо с помощью виртуального окружения python проект на ОС как демон. И это иногда будет даже лучше!
Список зависимостей вашего проекта в продакшене будет легко сравнить с тем, что используется в разработке.
Для этого не нужен venv внутри контейнера.
Нет необходимости в правах администратора, что может усложнить задачу злоумышленнику, пытающемуся проникнуть в ваш контейнер.
Для этого не нужен venv внутри контейнера.
Вы можете легко использовать сторонние инструменты, такие как uv, poetry или anaconda
Для этого не нужен venv внутри контейнера.
Вы можете иметь несколько venv с разными версиями Python или библиотек, чтобы быстро тестировать обновления. Это гораздо легче, чем использовать несколько образов.
А может тогда мы и несколько проектов будем запускать в одном контейнере. Это гораздо легче, чем использовать несколько образов.
Вы можете хранить ваш venv в отдельном томе, что позволяет отделить зависимости Python от самого образа.
Для этого не нужен venv внутри контейнера.
Если где-то и понадобится venv внутри контейнера, то для этого должны быть определенные условия, которые являются частным случаем, а не общим.
PostgreSQL всегда использовал модель многоверсионности (MVCC — Multi-Version Concurrency Control) для управления конкурентностью транзакций. Эта модель основана на использовании снимков данных (snapshot isolation) и была реализована с самого начала. Документация PostgreSQL 7.1.
Я немного запутал тем, что сначала начинается транзакция 2, а потом транзакция 1 (в тексте ниже это написано). Исправлю на картинке на транзакции 3 и 4 (чтобы нумерация была по порядку, как и на самом деле в Postgres).
А "фантомное чтение" тут имеется. Дело в том, что Repeatable Read предотвращает неповторяющиеся чтения для существующих строк, но НЕ для новых строк, которые могут быть добавлены другой транзакцией и удовлетворять условиям запроса. Что как раз изображено на рис. 2.13.
С точки зрения бизнес-логики это правильно, но не с точки зрения изоляции транзакций.
UNIQUE и EXCLUDE вызывают блокировки при проверке ограничений.
Также, если одна транзакция удаляет или изменяет запись, на которую ссылается другая запись через внешний ключ, другая транзакция, которая пытается создать или изменить запись, ссылающуюся на удаляемую или изменяемую запись, может быть заблокирована. Вторая транзакция должна ждать, пока первая транзакция завершится, чтобы проверить, остается ли ссылка валидной.
Стремиться к лучшему? Нет. Да и в чем сложность постараться создать минимальный образ для python? Это делается один раз на проект, да и во многих схожих проектах Dockerfile практически одинаковый, никаких трудностей там нет. Куча информации на хабре как создать минимальный и правильный Dockerfile.
Именно так!
Контейнер и так обеспечивает однородность, причем чистую, а не то что у вас может быть на рабочем компьютере, даже с venv.
Образ контейнера для python имеет много разных версий:
alpine
,slim
,bookworm
, и т.д. Всегда при сборке контейнера нужно выбирать, какой базовый образ выбрать для проекта. Затем устанавливаются дополнительные библиотеки и потом уже python зависимости. Если что-то когда-то сломается, то это знак, что нужно исправить ошибку в образе контейнера, а не брать самый тяжелыйpython:latest
и добавлять к нему виртуальное окружение отдельной папкой и смотреть на образ в 2 ГБ.Очень мало по сравнению с необразованностью и попыткой сделать как легче, а не как лучше. Мы же технически грамотные люди, нужно разбираться в том что делаем, тем более это в разы проще написания проекта.
Цель обеспечить минимум лишнего окружения для проекта и его прозрачного использования в чистой среде контейнера с конкретными зависимостями. Если это не требуется, то может и docker вовсе лишний. Можно запускать очень хорошо с помощью виртуального окружения python проект на ОС как демон. И это иногда будет даже лучше!
Для этого не нужен venv внутри контейнера.
Для этого не нужен venv внутри контейнера.
Для этого не нужен venv внутри контейнера.
А может тогда мы и несколько проектов будем запускать в одном контейнере. Это гораздо легче, чем использовать несколько образов.
Для этого не нужен venv внутри контейнера.
Если где-то и понадобится
venv
внутри контейнера, то для этого должны быть определенные условия, которые являются частным случаем, а не общим.Уточню, что можно обойтись лишь одним nginx, вместо двух, если в frontend конфигурации прописать для location /api/ перенаправление на backend
В начале каждой статьи добавил ссылки на другие
Спасибо, добавил!
Добавил больше информации на рис. 3.11.
Исправил рисунок 2.13
PostgreSQL всегда использовал модель многоверсионности (
MVCC
—Multi-Version Concurrency Control
) для управления конкурентностью транзакций. Эта модель основана на использовании снимков данных (snapshot isolation
) и была реализована с самого начала. Документация PostgreSQL 7.1.Уровень изоляции по умолчанию тоже всегда был
Read Committed
: документация PostgreSQL 7.1.Я немного запутал тем, что сначала начинается транзакция 2, а потом транзакция 1 (в тексте ниже это написано). Исправлю на картинке на транзакции 3 и 4 (чтобы нумерация была по порядку, как и на самом деле в Postgres).
А "фантомное чтение" тут имеется. Дело в том, что
Repeatable Read
предотвращает неповторяющиеся чтения для существующих строк, но НЕ для новых строк, которые могут быть добавлены другой транзакцией и удовлетворять условиям запроса. Что как раз изображено на рис. 2.13.С точки зрения бизнес-логики это правильно, но не с точки зрения изоляции транзакций.
Верно подмечено, исправил в тексте.
UNIQUE
иEXCLUDE
вызывают блокировки при проверке ограничений.Также, если одна транзакция удаляет или изменяет запись, на которую ссылается другая запись через внешний ключ, другая транзакция, которая пытается создать или изменить запись, ссылающуюся на удаляемую или изменяемую запись, может быть заблокирована. Вторая транзакция должна ждать, пока первая транзакция завершится, чтобы проверить, остается ли ссылка валидной.
Блокировки строк ещё имеют разные режимы — ссылка на документацию.
Очень много разных нюансов, которые не получается рассмотреть сразу. Может, когда-нибудь будет статья на эту тему.