Как стать автором
Обновить

Комментарии 10

  1. Про alpine - спорно. Нужно делать контейнеры как можно меньше, это уменьшает место для хранения (капитан очевидность), а также сокращает время запуска (привет nvidia с их 5 гиговыми образами).

  2. Я бы рекомендовал делать multistage-билды, чтобы исключить лишние библиотеки и опять же сократить размер образа

  3. Обязательно очищать образ после использования apt-get update

  4. Использовать пользователя для запуска процессов контейнера

  5. Про уменьшение размера- это уменьшение зависимостей, а соотвественно, уменьшение количества уязвимых компонентов на борту образа. Добавлю, что перед сборкой образа мы проверяем зависимости кода через owasp dependency checker, а в самом репозитории уже с помощью snyk. Если что-то выше уровня medium, то чешем репу и обновляем компоненты.

  6. Про не хранить образы на docker hub: с платной подпиской многие компании используют их приватные репы. Там snyk из коробки и возможность автосборки простых образов из gitlab и bitbucket, а также не нужно сопровождать свою инфраструктуру.

Спасибо за разумные дополнения. Плюсанул.

Alpine для питона не стоит использовать - https://habr.com/ru/post/486202/
Так же есть сценарий, что под альпин будут пропущены бинарные зависимости, для того же pydantic

Именно поэтому я и написал в статье то, что написал. Нынче на PyCon был доклад по поводу alpine. И там на примере pydantic было показано, что не стоит.

Спасибо за замечание и участие.

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

Я бы не был так категоричен: для ml - мы тоже используем стандартные образы от nvidia, а вот, всякие django и flask обязательно на alpine. Поэтому правы тут все)

Это проблема именно poetry; под pip тянется wheel. poetry вообще всё под alpine устанавливает из исходников - там баг в поиске правильных колёс. Но его починят в 1.2.

Думаю удобнее не прописывать значения переменных окружения прям в docker-compose. Если их оставить там без значений, то они будут проброщены с хоста или с файла .env

ый урок и оставленную в тезисах для запоминания ссылку на принцип единственной ответственности. При использовании точки входа процесс создания образа отделяется от слоя запуска сервиса и сервисных функций. При изменении списка входных команд мы не будем трогать dockerfile, и как следствие, нам не придётся во время локальной работы пересобирать сам образ.

всё равно не понял для чего конкретно этот код в entrypoint.sh. Разве явное не лучше неявного? По мне так entrypoint создан немного для другого — инициализация там всякая или предварительная проверка и ожидание доступности необходимых сервисов.

Думаю удобнее не прописывать значения переменных окружения прям в docker-compose. Если их оставить там без значений, то они будут проброщены с хоста или с файла .env

Это как вам будет угодно. Думаю, здесь никаких железобетонных правил нет. По большому счёту, смысл всего остального не меняется — используете вы мой вариант или ваш. Лично я не люблю .env, использую его редко. Не люблю из-за появляющихся через полгода-год test.env, test2.env, stage.env и т. д. Мне удобнее сразу в docker-compose энвы наблюдать и переопределять их в override.

----

Что касается второй части комментария, то мой ответ сильно зависит от того, что именно вы предлагаете взамен. Предположу, что CMD с некой дефолтной командой без использования docker-entrypoint.sh и аналогичным docker-compose.yml, где вместо моих command будет что-то вроде: command: "python <api/consumer>.py".

создан немного для другого — инициализация там всякая или предварительная проверка и ожидание доступности необходимых сервисов

Да. Видел, что для этого его в основном и используют, тут с вами не поспоришь. И я, признаться, не знаю, есть ли где-то скрижали, запрещающие иное предназначение.

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

В общем, можно определить только сервис:

service:
  container_name: python-garden_service
  image: python_garden
  build:
    context: .
  environment:
    PYTHONUNBUFFERED: 1
    SERVICE_DB_HOST: service_db
    SERVICE_DB_NAME: postgres
    SERVICE_DB_USERNAME: postgres
    EVENT_BROKER_HOST: mq
    EVENT_BROKER_PORT: 5672
    EVENT_BROKER_USERNAME: python_garden
  volumes:
    - .:/opt/lesson_2

Эта конфигурация послужит точкой входа вообще для любых команд. То есть вы можете через docker-compose run запускать оба инстанса и пробрасывать любую другую допустимую команду:

docker-compose run --rm service api
docker-compose run --rm service consumer
docker-compose run --rm service tests
docker-compose run --rm service bash ...
# et cetera

В этом случае docker-entrypoint.sh становится сугубо декларативным элементом.

В моём подходе имеется дублирование смыслов, согласен. То есть я объявляю типы запуска одновременно и в docker-entrypoint.sh, и в docker-compose.yml, что является избыточным.

согласен с тем что entrypoint можно использовать по разному. Docker очень гибкий инструмент.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации