Чому для встановлення Pandas на Alpine Linux потрібні віки


103

Я помітив, що встановлення Pandas та Numpy (це залежність) у контейнер Docker за допомогою базової ОС Alpine проти CentOS або Debian займає набагато більше часу. Я створив невеликий тест нижче, щоб продемонструвати різницю в часі. Окрім кількох секунд, які Alpine потребує для оновлення та завантаження залежностей збірки для встановлення Pandas та Numpy, чому setup.py займає приблизно в 70 разів більше часу, ніж при установці Debian?

Чи є спосіб прискорити встановлення, використовуючи Alpine як базове зображення, чи існує інше базове зображення, подібне до розміру Alpine, яке краще використовувати для таких пакетів, як Pandas та Numpy?

Dockerfile.debian

FROM python:3.6.4-slim-jessie

RUN pip install pandas

Створіть образ Debian за допомогою Pandas & Numpy:

[PandasDockerTest] time docker build -t debian-pandas -f Dockerfile.debian . --no-cache
    Sending build context to Docker daemon  3.072kB
    Step 1/2 : FROM python:3.6.4-slim-jessie
     ---> 43431c5410f3
    Step 2/2 : RUN pip install pandas
     ---> Running in 2e4c030f8051
    Collecting pandas
      Downloading pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl (26.2MB)
    Collecting numpy>=1.9.0 (from pandas)
      Downloading numpy-1.14.1-cp36-cp36m-manylinux1_x86_64.whl (12.2MB)
    Collecting pytz>=2011k (from pandas)
      Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
    Collecting python-dateutil>=2 (from pandas)
      Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB)
    Collecting six>=1.5 (from python-dateutil>=2->pandas)
      Downloading six-1.11.0-py2.py3-none-any.whl
    Installing collected packages: numpy, pytz, six, python-dateutil, pandas
    Successfully installed numpy-1.14.1 pandas-0.22.0 python-dateutil-2.6.1 pytz-2018.3 six-1.11.0
    Removing intermediate container 2e4c030f8051
     ---> a71e1c314897
    Successfully built a71e1c314897
    Successfully tagged debian-pandas:latest
    docker build -t debian-pandas -f Dockerfile.debian . --no-cache  0.07s user 0.06s system 0% cpu 13.605 total

Dockerfile.alpine

FROM python:3.6.4-alpine3.7

RUN apk --update add --no-cache g++

RUN pip install pandas

Створіть альпійський образ за допомогою Pandas & Numpy:

[PandasDockerTest] time docker build -t alpine-pandas -f Dockerfile.alpine . --no-cache
Sending build context to Docker daemon   16.9kB
Step 1/3 : FROM python:3.6.4-alpine3.7
 ---> 4b00a94b6f26
Step 2/3 : RUN apk --update add --no-cache g++
 ---> Running in 4b0c32551e3f
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/17) Upgrading musl (1.1.18-r2 -> 1.1.18-r3)
(2/17) Installing libgcc (6.4.0-r5)
(3/17) Installing libstdc++ (6.4.0-r5)
(4/17) Installing binutils-libs (2.28-r3)
(5/17) Installing binutils (2.28-r3)
(6/17) Installing gmp (6.1.2-r1)
(7/17) Installing isl (0.18-r0)
(8/17) Installing libgomp (6.4.0-r5)
(9/17) Installing libatomic (6.4.0-r5)
(10/17) Installing pkgconf (1.3.10-r0)
(11/17) Installing mpfr3 (3.1.5-r1)
(12/17) Installing mpc1 (1.0.3-r1)
(13/17) Installing gcc (6.4.0-r5)
(14/17) Installing musl-dev (1.1.18-r3)
(15/17) Installing libc-dev (0.7.1-r0)
(16/17) Installing g++ (6.4.0-r5)
(17/17) Upgrading musl-utils (1.1.18-r2 -> 1.1.18-r3)
Executing busybox-1.27.2-r7.trigger
OK: 184 MiB in 50 packages
Removing intermediate container 4b0c32551e3f
 ---> be26c3bf4e42
Step 3/3 : RUN pip install pandas
 ---> Running in 36f6024e5e2d
Collecting pandas
  Downloading pandas-0.22.0.tar.gz (11.3MB)
Collecting python-dateutil>=2 (from pandas)
  Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB)
Collecting pytz>=2011k (from pandas)
  Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
Collecting numpy>=1.9.0 (from pandas)
  Downloading numpy-1.14.1.zip (4.9MB)
Collecting six>=1.5 (from python-dateutil>=2->pandas)
  Downloading six-1.11.0-py2.py3-none-any.whl
Building wheels for collected packages: pandas, numpy
  Running setup.py bdist_wheel for pandas: started
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: still running...
  Running setup.py bdist_wheel for pandas: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/e8/ed/46/0596b51014f3cc49259e52dff9824e1c6fe352048a2656fc92
  Running setup.py bdist_wheel for numpy: started
  Running setup.py bdist_wheel for numpy: still running...
  Running setup.py bdist_wheel for numpy: still running...
  Running setup.py bdist_wheel for numpy: still running...
  Running setup.py bdist_wheel for numpy: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/9d/cd/e1/4d418b16ea662e512349ef193ed9d9ff473af715110798c984
Successfully built pandas numpy
Installing collected packages: six, python-dateutil, pytz, numpy, pandas
Successfully installed numpy-1.14.1 pandas-0.22.0 python-dateutil-2.6.1 pytz-2018.3 six-1.11.0
Removing intermediate container 36f6024e5e2d
 ---> a93c59e6a106
Successfully built a93c59e6a106
Successfully tagged alpine-pandas:latest
docker build -t alpine-pandas -f Dockerfile.alpine . --no-cache  0.54s user 0.33s system 0% cpu 16:08.47 total

1
.apk тепер доступний, тому нуль потрібно будувати з джерела - pkgs.alpinelinux.org/packages?name= * pandas & branch = edge
jtlz2

1
@ jtlz2, панди недоступні на краю гілки Альпійського моря. що шкода ...
fccoelho

@fccoelho Зараз він знову доступний!
jtlz2

Відповіді:


65

Зображення на основі Debian використовують лише python pipдля встановлення пакунків із .whlформатом:

  Downloading pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl (26.2MB)
  Downloading numpy-1.14.1-cp36-cp36m-manylinux1_x86_64.whl (12.2MB)

Формат WHL був розроблений як швидший та надійніший спосіб встановлення програмного забезпечення Python, ніж переробка кожного разу з вихідного коду. Файли WHL потрібно лише перемістити у правильне розташування в цільовій системі, яку потрібно встановити, тоді як вихідний дистрибутив вимагає кроку збірки перед установкою.

Пакети коліс pandasі numpyне підтримуються на зображеннях на платформі Alpine. Ось чому, коли ми встановлюємо їх з використанням python pipпід час процесу побудови, ми завжди компілюємо їх з вихідних файлів на alpine:

  Downloading pandas-0.22.0.tar.gz (11.3MB)
  Downloading numpy-1.14.1.zip (4.9MB)

і ми можемо побачити наступний внутрішній контейнер під час побудови зображення:

/ # ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c pip install pandas
    7 root       0:04 {pip} /usr/local/bin/python /usr/local/bin/pip install pandas
   21 root       0:07 /usr/local/bin/python -c import setuptools, tokenize;__file__='/tmp/pip-build-en29h0ak/pandas/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n
  496 root       0:00 sh
  660 root       0:00 /bin/sh -c gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DTHREAD_STACK_SIZE=0x100000 -fPIC -Ibuild/src.linux-x86_64-3.6/numpy/core/src/pri
  661 root       0:00 gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DTHREAD_STACK_SIZE=0x100000 -fPIC -Ibuild/src.linux-x86_64-3.6/numpy/core/src/private -Inump
  662 root       0:00 /usr/libexec/gcc/x86_64-alpine-linux-musl/6.4.0/cc1 -quiet -I build/src.linux-x86_64-3.6/numpy/core/src/private -I numpy/core/include -I build/src.linux-x86_64-3.6/numpy/core/includ
  663 root       0:00 ps aux

Якщо ми Dockerfileтрохи змінимо :

FROM python:3.6.4-alpine3.7
RUN apk add --no-cache g++ wget
RUN wget https://pypi.python.org/packages/da/c6/0936bc5814b429fddb5d6252566fe73a3e40372e6ceaf87de3dec1326f28/pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl
RUN pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl

ми отримуємо таку помилку:

Step 4/4 : RUN pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl
 ---> Running in 0faea63e2bda
pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl is not a supported wheel on this platform.
The command '/bin/sh -c pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl' returned a non-zero code: 1

На жаль, єдиний спосіб встановити pandasна альпійському зображенні - дочекатися закінчення збірки.

Звичайно, якщо ви хочете використовувати зображення Alpine з, pandasнаприклад, у CI, найкращий спосіб зробити це - скомпілювати його один раз, надіслати до будь-якого реєстру та використовувати як базовий образ для ваших потреб.

РЕДАГУВАТИ: Якщо ви хочете використовувати альпійський образ із собою, pandasви можете витягнути моє зображення докера nickgryg / alpine-pandas . Це зображення пітона з попередньо складеним pandasна альпійській платформі. Це має заощадити ваш час.


3
Ну, це дуже погано. Однак схоже на те, що шість, pytz і python-dateutil завантажують пакети .whl на Alpine. Чи означає це, що можна будувати колеса для панд і numpy для Alpine, але що цього зараз просто не відбувається?
moku

Ні, неможливо побудувати колеса для pandasnampy альпійської платформи та на ній. Ці колеса цього не підтримують. Я показав це у відповіді, коли намагався встановити pandasзі свого колеса пакет в альпійському образі.
nickgryg 02.03.18

@Nickolay Чи існує обхідний спосіб утилізації pandasзбірки, яка була побудована, alpineа потім кешована? (це може бути розміщено десь локально)
jtlz2,

2
Причина цього полягає в тому, що ці колеса містять двійкові файли, побудовані з c / c ++ і пов'язані з glibc, але альпійський не має glibc, він використовує musl, що означає, що нові двійкові файли повинні бути скомпільовані та пов'язані з musl.
ThisGuyCantВече

36

ВІДПОВІДЬ: НА 9.03.2020 ДЛЯ ПІФОНУ 3, ЩО ВСЕ НЕ!

Ось повний робочий файл Docker:

FROM python:3.7-alpine
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
RUN apk add --update --no-cache py3-numpy py3-pandas@testing

Збірка дуже чутлива до точних номерів версій пітона та альпійської версії - неправильне їх видавання провокує помилку Макса Леві so:libpython3.7m.so.1.0 (missing)- але вищесказане зараз працює для мене.

Мій оновлений файл Docker доступний за адресою https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b


[Раніше оновлення:]

ВІДПОВІДЬ: НЕ!

У будь-якому Alpine Dockerfile ви можете просто зробити *

RUN apk add py2-numpy@community py2-scipy@community py-pandas@edge

Це пов’язано з тим numpy, що scipyзараз pandasвсі доступні попередньо побудовані alpine:

https://pkgs.alpinelinux.org/packages?name=*numpy

https://pkgs.alpinelinux.org/packages?name=*scipy&branch=edge

https://pkgs.alpinelinux.org/packages?name=*pandas&branch=edge

Одним із способів уникнути перебудови кожного разу, або використання рівня Docker, є використання попередньо побудованого, власного Alpine Linux /.apk пакета, наприклад

https://github.com/sgerrand/alpine-pkg-py-pandas

https://github.com/nbgallery/apks

Ви можете побудувати їх .apk s один раз і використовувати їх де завгодно у вашому Dockerfile вам подобається :)

Це також позбавляє вас від необхідності вписувати все інше в образ Docker перед фактом - тобто гнучкість для попереднього створення будь-якого образу Docker, який вам подобається.

PS Я розмістив заглушку Dockerfile за адресою https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b, де приблизно показано, як будувати зображення. Сюди входять важливі кроки (*):

RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
RUN apk update
RUN apk add --update --no-cache libgfortran

2
Схоже, його нещодавно видалили? pkgs.alpinelinux.org/package/edge/testing/x86/py-pandas
jtlz2

1
@ChrisWedgwood Вони активно над цим працюють - див. Github.com/alpinelinux/aports/pull/6330
jtlz2,

1
@ChrisWedgwood Знову працюємо, тьху!
jtlz2


1
@ jtlz2 Я перейшов на 3.7-slim-buster і там все пройшло гладко pythonspeed.com/articles/base-image-python-docker-images
xristian

9

УВАГА
Подивіться на відповідь @ jtlz2 із останнім оновленням

ЗАСТАЛЕНИЙ

Отже, пакети py3-pandas & py3-numpy переміщені до тестового альпійського сховища, отже, ви можете завантажити його, додавши ці рядки у свій файл Docker:

RUN echo "http://dl-8.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
  && apk update \
  && apk add py3-numpy py3-pandas

Сподіваюся, це комусь допоможе!

Посилання на альпійські пакети:
- py3-pandas
- py3-numpy

Інформація про сховища Alpine зберігається .


Це спрацювало для мене! Дякуємо за надану оновлену відповідь!
Stratus3D

2
Виправлено у моїй відповіді
jtlz2

1
@ Jtlz2 круто, спасибі, але я переїхав в DEBiAN пиятика замість альпійської і спробував встановити техніка його підводить його знову з альпійськими, але в будь-якому випадку, спасибі за відповідь, а також фіксованої моя відповідь
stefanitsky

1
Тільки зауважимо, що py3-pandas недоступний для версії 3.11.x, він знаходиться лише у версії "edge" на момент написання цього коментаря. редагувати: Очевидно, там сказано, що у пості вище я просто пропустив це посилання раніше, вибачте.
гнилий

5

Просто збиратимуть деякі з цих відповідей в одній відповіді та додаватимуть деталь, яку я вважаю пропущеною. Причиною того, як певним бібліотекам python, особливо оптимізованим математичним бібліотекам і бібліотекам даних, так довго доводиться будувати на alpine, є те, що колеса піп для цих бібліотек включають двійкові файли, попередньо скомпільовані з c / c ++ і пов'язані з ними glibc, загальним набором стандартних бібліотек c. Всі Debian, Fedora, CentOS (як правило) використовують glibc, але musl-libcзамість цього використовує alpine, щоб залишатися легким . c / c ++ двійкові файли, побудовані на glibcсистемі, не працюватимуть в системі без, glibcте саме стосується іmusl .

Pip спочатку шукає колесо з правильними двійковими файлами, якщо не може знайти його, він намагається скомпілювати двійкові файли з джерела c / c ++ і пов'язує їх з musl. У багатьох випадках це навіть не спрацює, якщо у вас немає заголовків python з python3-devтаких інструментів, як make.

Зараз, як вже згадували інші, срібляста підкладка, є apkпакети з відповідними двійковими файлами, наданими спільнотою, використання яких допоможе вам заощадити (іноді тривалий) процес побудови двійкових файлів.


5

Справжня чесна порада тут, перейдіть на образ на основі Debian, і тоді всі ваші проблеми зникнуть.

Alpine для додатків python погано працює.

Ось приклад мого dockerfile:

FROM python:3.7.6-buster

RUN pip install pandas==1.0.0
RUN pip install sklearn
RUN pip install Django==3.0.2
RUN pip install cx_Oracle==7.3.0
RUN pip install excel
RUN pip install djangorestframework==3.11.0

Це python:3.7.6-busterбільш доречно в цьому випадку, крім того, вам не потрібна додаткова залежність в ОС.

Дотримуйтесь корисної та останньої статті: https://pythonspeed.com/articles/alpine-docker-python/ :

Не використовуйте Alpine Linux для зображень на Python, якщо ви не хочете значно повільніший час побудови, більші зображення, більше роботи та потенційні незрозумілі помилки, ви хочете уникати Alpine Linux як базового зображення. Деякі рекомендації щодо того, що слід використовувати, див. У моїй статті про вибір хорошого базового зображення.


1
Ви можете зменшити кількість шарів у своєму зображенні, тобто RUN pip install <packegeA> && pip install <packageB> тощо, замість того, щоб використовувати блок команд RUN. Це впливає на ефективність вашої збірки :)
p0l00ck

Ви також pip --no-cacheможете збрити трохи більше сліду. Що ви насправді повинні зробити, це просто помістити їх рядок за рядком у requirements.txtфайл іpip install --no-cache -r requirements.txt
ThisGuyCantEven

1

Це працювало для мене:

FROM python:3.8-alpine
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
RUN apk add --update --no-cache py3-numpy py3-pandas@testing
ENV PYTHONPATH=/usr/lib/python3.8/site-packages

COPY . /app
WORKDIR /app

RUN pip install -r requirements.txt

EXPOSE 5003 
ENTRYPOINT [ "python" ] 
CMD [ "app.py" ]

Більша частина коду тут - з відповіді jtlz2 з тієї ж теми та Faylixe з іншого потоку.

Виявляється, полегшену версію панд можна знайти у сховищі Alpine, py3-numpyале вона не встановлюється в тому ж шляху до файлу, звідки Python за замовчуванням читає імпорт. Тому вам потрібно додати ENV. Також пам’ятайте про альпійську версію.


0

pandas вважається пакетом, що підтримується громадою, тому відповіді вказують на edge/testing , не будуть працювати, оскільки Alpine офіційно не підтримує панди як основний пакет (він все ще працює, його просто не підтримують основні розробники Alpine).

Спробуйте цей файл Docker:

FROM python:3.8-alpine
RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
&& apk add py3-pandas@community

Це працює і для ванільного альпійського зображення, використовуючи FROM alpine:3.12.


-1

alpine вимагає багато часу для встановлення панд, і розмір зображення також величезний. Я спробував версію базового зображення python: 3.8-slim-buster. Створення зображення було дуже швидким, а розмір зображення був менше половини в порівнянні з зображенням альпійського пітона

https://github.com/dguyhasnoname/k8s-cluster-checker/blob/master/Dockerfile

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.