Alpine linux install python

Так ли мал Alpine 3.8 Docker для Python 3 runtime

Совсем недавно произошёл релиз минималистичного Alpine Linux 3.8. Очень часто данный linux образ используют в докере, собирая очень компактные окружения для runtime.

Сегодняшняя статья будет рассмотрена в срезе использования runtime системы в докере для Python 3.6.X версий, с различным составом пакетов pip. А так же мы соберём самый новый Python 3.7 в Alpine.

  1. Система, ее обновление. И Python3 с обновлённым pip (10 версии)
  2. п.1 + tornado cython
  3. п.2 + numpy-scipy
  4. п.3 + pillow bokeh pandas websocket-client

Итак, результирующие файлы для Debian и Fedora будут выглядеть у нас так:
Debian

FROM debian RUN apt-get update -y && apt-get install python3-pip -y && pip3 install pip --upgrade && apt-get clean RUN pip3 install cython tornado websocket-client pytest numpy pandas scipy bokeh pillow 
FROM fedora RUN dnf update -y && dnf install libstdc++ -y && dnf clean all && pip3 install --upgrade pip && python3 --version RUN pip3 install cython tornado websocket-client pytest numpy pandas scipy bokeh pillow

А вот с Alpine 3.8 пока заминка. Официально на момент написания статьи он ещё на вышел, а посмотреть, то хочется:-). Поэтому нам понадобиться их образ системы:
dl-cdn.alpinelinux.org/alpine/v3.8/releases/x86_64
И мы соберём свой Alpine from Sratch:
github.com/gliderlabs/docker-alpine/tree/master/versions/library-3.8/x86_64

FROM scratch ADD alpine3.8.tar.gz / ENV RELEASE="v3.8" ENV MIRROR="http://dl-cdn.alpinelinux.org/alpine" ENV PACKAGES="alpine-baselayout,busybox,alpine-keys,apk-tools,libc-utils" ENV TAGS=(alpine:3.8) 

Затем копипастим и добавляем в этот файл борку Python 3.6 со страницы github.com/docker-library/python/blob/master/3.6/alpine3.7/Dockerfile
не забыв удалить или закомментировать строку FROM alpine:3.7

Читайте также:  Html код страницы битрикс

И пробуем создать образ с Alpine 3.8 и Python на борту:

$docker build -t alpine3.8 . #результат работы (последние строки) (1/2) Purging .fetch-deps (0) (2/2) Purging libressl (2.7.4-r0) Executing busybox-1.28.4-r0.trigger OK: 33 MiB in 45 packages + python get-pip.py --disable-pip-version-check --no-cache-dir 'pip==10.0.1' Collecting pip==10.0.1 Downloading https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl (1.3MB) Collecting setuptools Downloading https://files.pythonhosted.org/packages/7f/e1/820d941153923aac1d49d7fc37e17b6e73bfbd2904959fffbad77900cf92/setuptools-39.2.0-py2.py3-none-any.whl (567kB) Collecting wheel Downloading https://files.pythonhosted.org/packages/81/30/e935244ca6165187ae8be876b6316ae201b71485538ffac1d718843025a9/wheel-0.31.1-py2.py3-none-any.whl (41kB) Installing collected packages: pip, setuptools, wheel Successfully installed pip-10.0.1 setuptools-39.2.0 wheel-0.31.1 + pip --version pip 10.0.1 from /usr/local/lib/python3.6/site-packages/pip (python 3.6) + find /usr/local -depth '(' '(' -type d -a '(' -name test -o -name tests ')' ')' -o '(' -type f -a '(' -name '*.pyc' -o -name '*.pyo' ')' ')' ')' -exec rm -rf '<>' + + rm -f get-pip.py ---> f7439dca5f31 Removing intermediate container e1fcd1c74873 Step 17/17 : CMD python3 ---> Running in a4dc6dfa5184 ---> 6924b206c6b9 Removing intermediate container a4dc6dfa5184 Successfully built 6924b206c6b9 

Шаг 2. Установка cython и tornado

Начинаем добавлять пакеты pip. Первым установим cython и tornado. Для Debian и Fedora пакеты ставятся без ошибок, а вот Alpine падает с ошибкой:

unable to execute 'gcc': No such file or directory error: command 'gcc' failed with exit status 1

Придется гуглить и потом уже добавлять библиотеки сборки в Alpine, чтобы pip успешно собрал их из исходного текста. Затем запускать сборку докера снова, затем опять искать зависимости, читать форумы stackoverflow и issues в github и ждать и ждать и ждать.

Поскольку в следующих шагах мы начнём добавлять математические и графические библиотеки в наш образ runtime Python, и чтобы слишком не увеличивать текст данной статьи, я приведу финальные зависимости для Alpine linux:

 apk add --no-cache --virtual .build-deps \ gfortran \ build-base \ openblas-dev \ bzip2-dev \ coreutils \ dpkg-dev dpkg \ expat-dev \ gcc \ gdbm-dev \ libc-dev \ libffi-dev \ libnsl-dev \ libressl \ libressl-dev \ libtirpc-dev \ linux-headers \ make \ ncurses-dev \ pax-utils \ readline-dev \ sqlite-dev \ tcl-dev \ tk \ tk-dev \ xz-dev \ zlib-dev \ libxml2-dev \ libxslt-dev \ musl-dev \ libgcc \ curl \ jpeg-dev \ zlib-dev \ freetype-dev \ lcms2-dev \ openjpeg-dev \ tiff-dev \ tk-dev \ tcl-dev \ && ln -s /usr/include/locale.h /usr/include/xlocale.h

Шаг 3. Добавляем математику numpy scipy

Шаг 4. Добавляем графический стек websocket-client pytest pandas bokeh pillow

 FROM scratch ADD alpine3.8.tar.gz / CMD ["/bin/sh"] ENV RELEASE="v3.8" ENV MIRROR="http://dl-cdn.alpinelinux.org/alpine" ENV PACKAGES="alpine-baselayout,busybox,alpine-keys,apk-tools,libc-utils" #ENV BUILD_OPTIONS=(-b -s -t UTC -r $RELEASE -m $MIRROR -p $PACKAGES) ENV TAGS=(alpine:3.8) # # NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh" # # PLEASE DO NOT EDIT IT DIRECTLY. # #https://github.com/docker-library/python/blob/master/3.6/alpine3.7/Dockerfile # ensure local python is preferred over distribution python ENV PATH /usr/local/bin:$PATH # http://bugs.python.org/issue19846 # > At the moment, setting "LANG=C" on a Linux system *fundamentally breaks Python 3*, and that's not OK. ENV LANG C.UTF-8 # install ca-certificates so that HTTPS works consistently # the other runtime dependencies for Python are installed later RUN apk add --no-cache ca-certificates ENV GPG_KEY 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D ENV PYTHON_VERSION 3.6.6 RUN set -ex \ && apk add --no-cache --virtual .fetch-deps \ gnupg \ libressl \ tar \ xz \ \ && wget -O python.tar.xz "https://www.python.org/ftp/python/$/Python-$PYTHON_VERSION.tar.xz" \ && wget -O python.tar.xz.asc "https://www.python.org/ftp/python/$/Python-$PYTHON_VERSION.tar.xz.asc" \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$GPG_KEY" \ && gpg --batch --verify python.tar.xz.asc python.tar.xz \ && rm -rf "$GNUPGHOME" python.tar.xz.asc \ && mkdir -p /usr/src/python \ && tar -xJC /usr/src/python --strip-components=1 -f python.tar.xz \ && rm python.tar.xz \ \ && apk add --no-cache --virtual .build-deps \ bzip2-dev \ coreutils \ dpkg-dev dpkg \ expat-dev \ gcc \ gdbm-dev \ libc-dev \ libffi-dev \ libnsl-dev \ libressl \ libressl-dev \ libtirpc-dev \ linux-headers \ make \ ncurses-dev \ pax-utils \ readline-dev \ sqlite-dev \ tcl-dev \ tk \ tk-dev \ xz-dev \ zlib-dev \ # add build deps before removing fetch deps in case there's overlap && apk del .fetch-deps \ \ && cd /usr/src/python \ && gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \ && ./configure \ --build="$gnuArch" \ --enable-loadable-sqlite-extensions \ --enable-shared \ --with-system-expat \ --with-system-ffi \ --without-ensurepip \ && make -j "$(nproc)" \ # set thread stack size to 1MB so we don't segfault before we hit sys.getrecursionlimit() # https://github.com/alpinelinux/aports/commit/2026e1259422d4e0cf92391ca2d3844356c649d0 EXTRA_CFLAGS="-DTHREAD_STACK_SIZE=0x100000" \ && make install \ \ && runDeps="$( \ scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ | tr ',' '\n' \ | sort -u \ | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 < next >< print "so:" $1 >' \ )" \ && apk add --virtual .python-rundeps $runDeps \ && apk del .build-deps \ \ && find /usr/local -depth \ \( \ \( -type d -a \( -name test -o -name tests \) \) \ -o \ \( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \ \) -exec rm -rf '<>' + \ && rm -rf /usr/src/python # make some useful symlinks that are expected to exist RUN cd /usr/local/bin \ && ln -s idle3 idle \ && ln -s pydoc3 pydoc \ && ln -s python3 python \ && ln -s python3-config python-config # if this is called "PIP_VERSION", pip explodes with "ValueError: invalid truth value ''" ENV PYTHON_PIP_VERSION 10.0.1 RUN set -ex; \ \ apk add --no-cache --virtual .fetch-deps libressl; \ \ wget -O get-pip.py 'https://bootstrap.pypa.io/get-pip.py'; \ \ apk del .fetch-deps; \ \ python get-pip.py \ --disable-pip-version-check \ --no-cache-dir \ "pip==$PYTHON_PIP_VERSION" \ ; \ pip --version; \ \ find /usr/local -depth \ \( \ \( -type d -a \( -name test -o -name tests \) \) \ -o \ \( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \ \) -exec rm -rf '<>' +; \ rm -f get-pip.py apk add --no-cache --virtual .build-deps \ gfortran \ build-base \ openblas-dev \ bzip2-dev \ coreutils \ dpkg-dev dpkg \ expat-dev \ gcc \ gdbm-dev \ libc-dev \ libffi-dev \ libnsl-dev \ libressl \ libressl-dev \ libtirpc-dev \ linux-headers \ make \ ncurses-dev \ pax-utils \ readline-dev \ sqlite-dev \ tcl-dev \ tk \ tk-dev \ xz-dev \ zlib-dev \ libxml2-dev \ libxslt-dev \ musl-dev \ libgcc \ curl \ jpeg-dev \ zlib-dev \ freetype-dev \ lcms2-dev \ openjpeg-dev \ tiff-dev \ tk-dev \ tcl-dev \ && ln -s /usr/include/locale.h /usr/include/xlocale.h \ && pip install cython tornado websocket-client pytest numpy pandas scipy bokeh pillow \ && apk del .build-deps \ && apk add --no-cache libstdc++ openblas zlib jpeg openjpeg tiff tk tcl musl libxml2 libxslt xz zlib libstdc++ openblas \ && pip list CMD ["python3"] 

В качестве бонуса, попробуем в Alpine 3.8 скомпилировать ещё не вышедший для докера Python 3.7.
Новая версия Python 3.7 представлена 27 июня 2018 года

Package Version ---------------- ------- atomicwrites 1.1.5 attrs 18.1.0 bokeh 0.13.0 Cython 0.28.3 Jinja2 2.10 MarkupSafe 1.0 more-itertools 4.2.0 numpy 1.14.5 packaging 17.1 pandas 0.23.1 Pillow 5.1.0 pip 10.0.1 pluggy 0.6.0 py 1.5.4 pyparsing 2.2.0 pytest 3.6.2 python-dateutil 2.7.3 pytz 2018.4 PyYAML 4.1 scipy 1.1.0 setuptools 39.2.0 six 1.11.0 tornado 5.0.2 websocket-client 0.48.0 wheel 0.31.1 ---> 3d18b8c27cd9 Removing intermediate container f546e004b79f Step 18/18 : CMD python3 ---> Running in 23c5aea50a0d ---> d5385e425064 Removing intermediate container 23c5aea50a0d Successfully built d5385e425064 real 41m17,619s 

Размер Alpine 3.8 с Python 3.7 с текущим списком пакетов pip 656 MB

Итоги

  • Debian 9 / больше в 6.24х / +430 Mb
  • Fedora 28 / больше в 4,7х / +304 Mb
  • Debian 9 / больше в 3,71х / +390 Mb
  • Fedora 28 / больше в 2,82x / +263 Mb

При большом количестве графических пакетов, оптимальнее выбрать дистрибутив Fedora, чем заниматься компиляцией пакетов в Alpine (компиляция может длиться 1-2 часа), и в результате получить экономию в один или два десятка процентов места на жёстком диске.

UPDATE1: Тестирование проводилось на Fedora Atomic Host: release 28 (Twenty Eight), Version: 2018.5

UPDATE2: Проверка занимаемого места на диске, была проведена по данному билду hub.docker.com/r/flytrue/python-runtime-docker/tags

$docker pull flytrue/python-runtime-docker:alpine-full $docker save flytrue/python-runtime-docker:alpine-full -o alpine-full.tar $ls -lh alpine-full.tar -rw-------. 1 fedora fedora 631M июн 29 08:38 alpine-full.tar $ docker images --all|grep alpine docker.io/flytrue/python-runtime-docker alpine-full f37154658671 19 hours ago 650 MB 

Источник

Install Python on Alpine Linux — Docker

In order to install Python on Alpine Linux the smallest and most security-oriented Linux distribution mostly used with Docker, you will need to make use of the apk — the alpine package manager.

% docker run -it --name python-with-alpine alpine #  fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/aarch64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/aarch64/APKINDEX.tar.gz (1/13) Installing libbz2 (1.0.8-r1) (2/13) Installing expat (2.4.8-r0) (3/13) Installing libffi (3.4.2-r1) (4/13) Installing gdbm (1.23-r0) (5/13) Installing xz-libs (5.2.5-r1) (6/13) Installing libgcc (11.2.1_git20220219-r2) (7/13) Installing libstdc++ (11.2.1_git20220219-r2) (8/13) Installing mpdecimal (2.5.1-r1) (9/13) Installing ncurses-terminfo-base (6.3_p20220521-r0) (10/13) Installing ncurses-libs (6.3_p20220521-r0) (11/13) Installing readline (8.1.2-r0) (12/13) Installing sqlite-libs (3.38.5-r0) (13/13) Installing python3 (3.10.5-r0) Executing busybox-1.35.0-r17.trigger OK: 57 MiB in 27 packages# python3 --version Python 3.10.5

You can also get it installed using the RUN instruction in a Dockerfile,

Python3 on Alpine Linux using Dockerfile

FROM alpine:latest RUN apk add python3 CMD python3 --version
% docker build -t alpine-python . % docker run -it alpine-python Python 3.10.5

Источник

Оцените статью