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

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

Переводите тогда уже и комментарии:

First «the Dockerfiles in this article are not examples of best practices»

Well, that's a big mistake. Of course if you don't follow best practices you won't get the best results. In these examples the author doesn't even follow the basic recommendations from the Docker Alpine image page. Ex, use «apk add --no-cache PACKAGE». When you're caching apt & apk, of course the image is going to be a ton larger. On the flip side he does basically exactly that to clean up ubuntus apt cache.

The real article should have been «should you use alpine for every python/docker project?» and the answer is «No». If you're doing something complicated that requires a lot of system libs, like say machine learning or imagine manipulation — don't use Alpine. It's a pain. On the flip side if all you need is a small flask app, Alpine is a great solution.
Увы, для production обычно нужен gunicorn/uwsgi/gevent/uvloop и доступ к ресурсам (psycopg2-binary/hiredis), а они опять таки — требуют wheels и некоторые библиотеки (libc-compat, libev).
Потому — multi-stage с python:3 и python:3-slim будут лучшим доступным решением.

ИМХО: Батарейки — главное преимущество Python, и главный его недостаток.
Alpine не поддерживает wheels

Он поддерживает wheels, это manylinux1 не поддерживается.

Мне кажется изначально довольно странным решением — брать максимально урезанный и ограниченный образ и собирать на нем расфуфыренный библиотеками питон.

Нет, это проблески надежды, что оптимальное решение для одного случая будет оптимальным для всего. И, да, эльпайн переоценен. Хочешь минималка — бери FROM scratch и наполняй его сам

ну это не новость, что из-за musl в Alpine может быть много проблем.


Большой привет некоторым программистам на Си, беззаботно пихающим зависимости от glibc и т.п. в свои проекты, даже когда им вполне хватило бы POSIX.

НЛО прилетело и опубликовало эту надпись здесь

Здесь правых нет. Виноваты все

Давно уже не использую alpine для чего-то, что требует докерфайл больше пары строк.
Просто потому что задолбаешься выяснять как поставить какие-то библиотеки для него, а лишние 50 Мб роли особо не играют.

Зато стоимость разработки вырастает, т.к. эти зависимости надо искать. А потом поддерживать в актуальном состоянии, когда нужно образ пересобирать.
Плюс проблема с долгой сборкой или установкой numpy/pandas/scikit не надуманна

Вместо
RUN apk --update add gcc build-base
Лучше использовать
RUN apk --no-cache add gcc build-base


И после установки зависимостей python можно удалить часть пакетов, не нужных в runtime.


Может будет лучше)

И после установки зависимостей python можно удалить часть пакетов, не нужных в runtime.
Для этого, кстати, у apk есть удобная опция --virtual:
RUN apk add --no-cache --virtual .build-deps gcc freetype-dev libpng-dev openblas-dev \
    && ./configure \
    && make \
    && ... \
    && apk del .build-deps       


Именно. Это тот самый комментарий, который показывает, что автор изначальной статьи просто не разобрался как в alpine устанавливать питоновские либы. PS. Использую alpine с python больше 3 лет, с правильным подходом проблем ни с чем нк возникает.

с правильным подходом вообще всегда проблем нет :)
Только при этом ты жертвуешь временем сборки, или размером образа (будет слой, который содержит весь build-deps). В случае с alpine — удобно работать только с статически линованными приложениями (привет Golang/JVM!), или приходится городить multistage.
Для себя проблему решили переборкой всех зависимостей и PYPI-proxy.

Как мне кажется — проблема не в alpine, а в отсутствии платформо-зависимых пакетов для него. ИМХО.

Касательно времени сборки — да, верное замечание, что если бы были готовые бинари, то мы не "попадали" бы на время сборки. Кстати, время сборки отчасти можно победить путем сборки СВОЕГО базового образа из alpine + самые часто используемые и долго собираемые зависимости. А потом уже в самом проекте докидывать из requirements.txt все остальное. Датасайентисты и инженеры так и делают. Ну, и версии пакетов зафиксированы — это тоже благо

Глупость говорите. Единственное с чем согласен — эльпайн требует отдельного подхода. Но это точно нельзя назвать 'правильным'.
Я уж не говорю, когда занимаетесь ml — попробуйте тот же torch или tensorflow водрузить на эльпайн. А ещё весело, когда у тебя проект состоит из 20 образов, разработчики все собрали из чего попало — что из эльпайна, что из убунту. В результате получается, что если все образы привести к единой общей базе, то они и качаются быстрее, и суммарно меньше места занимают, чем если они собраны из разных базовых.

Не смотря на некоторые недочёты в использовании apk и в целом использования, спасибо за этот перевод. Я как-то не задумывался, что, возможно, некоторые тормоза и непонятного происхождения ошибки могут быть из-за musl. Думаю это отличный повод для исследования.

Одна из проблем, с которой мы столкнулись: https://github.com/jrottenberg/ffmpeg/issues/104
Было ОЧЕНЬ больно, т.к. это не бинарная история, что нечто либо работает, либо не работает, а ошибка проявлялась только при определенном наборе аргументов ffmpeg (facepalm)

Ой ну прямо так часто вы будете пересобирать все библиотеки. Докер билд кэш рулит.
Зачем здесь перевод этой убогой статьи от восьмиклассника, который не умеет собирать образы на alpine на достаточном уровне, чтобы приводить такие бенчи?
Выше в комментариях уже отметили.

Вы хабр с лором не перепутали случаем? Что не так в статье кроме некоторых формулировок? wheels есть, собранные с musl? Нет. Ну вот и всё. Восьмиклассник он или нет, роли не играет, если вам нужен какой-нибудь SciPy, вы его задолбётесь собирать со всеми этими openblas/atlas/fortran как по времени так и по всяким траблам, которые могут внезапно вылезти.


Проект manylinux стал прорывом в своё время, он сильно облегчил жизнь людям, использующим Python-пакеты с C-extensions. Не стоит это недооценивать.

У alpine есть проблемы с библиотеками. На этом все. Всё остальное что описал автор оригинала — проблемы автора, потому что он не умеет пользоваться докером и собирать образы правильно.

Была такая проблема — куча докер контейнеров на alpine с пандой. Решение было несложное — подготовить образ с установленными numpy и pandas и использовать его как базовый для всех этих пакетов. И всё, CI снова быстр.
Если использовать двухшаговую сборку, то и продакш-контейнеры будут не такими тяжёлыми, и сборка с кешем будет практически мгновенной.
Но это если у вас не слишком много разной тяжести в духе pandas'а и т.п.

Я использую вот такое для вебсервиса на sanic, в котором используются допом aiohttp, asyncpg, honeybadger, Jinja2, Pillow. Если pillow не нужен, то, например, jpeg-dev будет не нужен, контейнер будет меньше.

FROM python:3.7.5-alpine3.10 as base

FROM base as builder
RUN mkdir /install
WORKDIR /install
RUN apk add --no-cache python3-dev \
                       build-base \
                       libc6-compat \
                       libffi-dev \
                       zlib-dev \
                       jpeg-dev \
                       linux-headers
RUN pip3 install --upgrade pip
COPY requirements.txt ./
RUN pip3 install --prefix=/install -r requirements.txt

FROM base
RUN apk add --no-cache bash jpeg-dev && \
    rm -r /tmp
EXPOSE 80
WORKDIR my_awesome_app
COPY --from=builder /install /usr/local
COPY my_awesome_app ./
RUN pip3 freeze
CMD ["python3", "app.py"]

Продакшн-контейнер получается 160MB.

Собрать мой стек на ubuntu/debian за быстро не получилось, поэтому, увы, без сравнения.

Двухшаговая сборка всё равно выглядит как какой-то dirty hack. В идеале помимо multi-stage build должна существовать система, в которой строятся параллельно два связанных образа: билд-образ и prod-образ. На prod-образе не должно быть ни package manager'а и всех его метаданных по установленным пакетам, ни даже busybox'а (если речь про alpine), если нам не нужен busybox. В принципе по минимуму это должен быть один лишь musl и нужное приложение (если оно больше ничего за собой не тянет). В минимальном же образе alpine 14 пакетов, большая часть которых нужна для apk.

Если пропустить все уже вышеназванное, то скорость создания образа можно вернуть установкой уже собранного пакета pandas.
apk add py3-pandas@testing py3-matplotlib@testing
Проверьте скорость собирания образа после этого :) Да, тестовая ведка означает что ваш пакет не проверяли полностью. В лучшем случае в нем есть юниттесты которые проверяют стандартно работоспособность библиотеки, в худшем вы можете иметь пакет который собран наобум. Все от случая к случаю, но если вы здесь, скорее всего вы маленькая часть пользователей Alpine которые имеют очень специфичные требования что не нужны для 90% другой аудиенции of Alpine.


В чем проблема? Видимо в том что разработчики pandas поналепили туда хаос зависимостей, которые в свою очередь имеют тоже тучу зависимостей, которые… И так несколько уровней. Огромное количество зависимостей понятное дело используют стандартный C, не musl, и требуют отдельной компиляции. Alpine сообщество разработчиков в целом решило не гадить своими "колесами" основной репозиторий pypi, и вместо этого просто компилит и пакует свои питоновые пакеты (в том числе pandas который из-за своего количества зависимостей занимает 1 час компиляции). Хорошо ли это, когда колеса не постятся "как обычно"? Наверно не очень для тех кто только в питоне разбирается, а в Alpine нет.


Однако самая большая вещь которая упускается здесь это то, что Alpine по своей сущности в основном для кручения на маломощном hardware или для контейнеров чтобы понизить footprint в безопасности (много программ = много дыр), и в ресурсоемкости (если последовать всем вышесказанным рекомендациям, образ будет в два раза меньше все равно) + меньше потребление памяти/CPU т.к. меньше фигни добавлено которая всегда идет с чем-то новоустановленным.

Привет из 2024!
Попалась на глаза заметка, и я, из любопытства повторил эксперимент с более свежими образами.
И вот что хочу по этому поводу отметить:

  • Ubuntu 22.04 (LTS) vs alpine 3.19, скорость сборки примерно одинакова(23 сек vs 18 сек), размер 214MB (ubuntu-gcc) vs 154MB (alpine-gcc)

  • в alpine 3.19 pip качает .whl

  • размеры финальных образов: 356MB (python-slim) vs 279MB (python-alpine), время сборки 27 сек у slim и 32 сек у alpine

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации