Mengapa perlu waktu lama untuk menginstal Pandas di Alpine Linux

107

Saya perhatikan bahwa menginstal Pandas dan Numpy (ketergantungannya) di wadah Docker menggunakan basis OS Alpine vs. CentOS atau Debian membutuhkan waktu lebih lama. Saya membuat tes kecil di bawah ini untuk mendemonstrasikan perbedaan waktu. Selain beberapa detik yang dibutuhkan Alpine untuk memperbarui dan mengunduh dependensi build untuk menginstal Pandas dan Numpy, mengapa setup.py membutuhkan waktu sekitar 70x lebih banyak daripada saat menginstal Debian?

Apakah ada cara untuk mempercepat penginstalan menggunakan Alpine sebagai gambar dasar atau adakah gambar dasar lain dengan ukuran yang sebanding dengan Alpine yang lebih baik digunakan untuk paket seperti Pandas dan Numpy?

Dockerfile.debian

FROM python:3.6.4-slim-jessie

RUN pip install pandas

Bangun image Debian dengan 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

Bangun gambar Alpine dengan 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
moku
sumber
2
.apk sekarang tersedia, jadi tidak perlu membangun dari sumber - pkgs.alpinelinux.org/packages?name= * pandas & branch = edge
jtlz2
2
@ jtlz2, panda tidak tersedia di tepi cabang Alpine. yang disayangkan ...
fccoelho
@fccoelho Tersedia lagi sekarang!
jtlz2

Jawaban:

67

Gambar berbasis Debian hanya digunakan python pipuntuk menginstal paket dengan .whlformat:

  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)

Format WHL dikembangkan sebagai metode yang lebih cepat dan lebih andal untuk menginstal perangkat lunak Python daripada membangun kembali dari kode sumber setiap saat. File WHL hanya perlu dipindahkan ke lokasi yang benar pada sistem target untuk diinstal, sedangkan distribusi sumber memerlukan langkah build sebelum instalasi.

Paket roda pandasdan numpytidak didukung dalam gambar berdasarkan platform Alpine. Itulah mengapa ketika kami menginstalnya menggunakan python pipselama proses pembuatan, kami selalu mengkompilasinya dari file sumber di alpine:

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

dan kita bisa melihat wadah di dalam berikut selama pembuatan gambar:

/ # 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

Jika kami memodifikasi Dockerfilesedikit:

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

kami mendapatkan kesalahan berikut:

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

Sayangnya, satu-satunya cara untuk menginstal pandaspada image Alpine adalah menunggu sampai build selesai.

Tentu saja jika Anda ingin menggunakan gambar Alpine dengan pandasdi CI misalnya, cara terbaik untuk melakukannya adalah dengan mengkompilasinya sekali, dorong ke registri mana saja dan gunakan sebagai gambar dasar untuk kebutuhan Anda.

EDIT: Jika Anda ingin menggunakan gambar Alpine dengan pandasAnda dapat menarik gambar buruh pelabuhan nickgryg / alpine-pandas saya . Ini adalah gambar python dengan pra-kompilasi pandaspada platform Alpine. Ini akan menghemat waktu Anda.

nickgryg
sumber
3
Yah, itu sangat buruk. Namun, sepertinya six, pytz, dan python-dateutil mengunduh paket .whl di Alpine. Apakah itu berarti mungkin untuk membuat roda untuk panda dan numpy untuk Alpine, tetapi itu tidak terjadi saat ini?
moku
Tidak, tidak mungkin membuat roda untuk pandasdan di nampyatas platform alpine. Roda itu tidak mendukungnya. Saya menunjukkan itu dalam jawaban, ketika mencoba menginstal pandasdari paket rodanya dalam gambar alpine.
nickgryg
@Nickolay Adakah cara alternatif untuk mendaur ulang pandasbangunan yang telah dibangun alpinedan kemudian disimpan dalam cache? (ini dapat dihosting di suatu tempat secara lokal)
jtlz2
2
Alasannya begini adalah karena roda ini berisi binari yang dibangun dari c / c ++ dan dihubungkan dengan glibc, tetapi alpine tidak memiliki glibc, melainkan menggunakan musl, yang berarti binari baru harus dikompilasi dan ditautkan dengan musl.
ThisGuyCantEven
36

JAWABAN: PADA 3/9/2020, UNTUK PYTHON 3, MASIH TIDAK!

Berikut adalah Dockerfile yang berfungsi lengkap:

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

Build sangat sensitif terhadap nomor versi python dan alpine yang tepat - kesalahan ini tampaknya memicu kesalahan Max Levy so:libpython3.7m.so.1.0 (missing)- tetapi yang di atas sekarang berfungsi untuk saya.

Dockerfile saya yang diperbarui tersedia di https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b


[Pembaruan Sebelumnya:]

JAWABAN: TIDAK!

Di Alpine Dockerfile, Anda cukup melakukan *

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

Ini karena numpy, scipydan sekarang pandassemuanya telah tersedia sebelumnya di 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

Salah satu cara untuk menghindari pembangunan kembali setiap saat, atau menggunakan lapisan Docker, adalah dengan menggunakan .apkpaket / Linux Alpine bawaan yang sudah dibuat sebelumnya, misalnya

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

https://github.com/nbgallery/apks

Anda dapat membangun ini .apksekali dan menggunakannya di mana pun di Dockerfile Anda yang Anda suka :)

Ini juga membuat Anda tidak perlu memanggang semua yang lain ke dalam image Docker sebelum fakta - yaitu fleksibilitas untuk membuat image Docker terlebih dahulu yang Anda suka.

PS Saya telah meletakkan rintisan Dockerfile di https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b yang menunjukkan secara kasar bagaimana membangun image. Ini termasuk langkah-langkah penting (*):

RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
RUN apk update
RUN apk add --update --no-cache libgfortran
jtlz2.dll
sumber
2
Sepertinya baru saja dihapus? pkgs.alpinelinux.org/package/edge/testing/x86/py-pandas
jtlz2
1
@ChrisWedgwood Mereka secara aktif mengerjakannya - lihat github.com/alpinelinux/aports/pull/6330
jtlz2
1
@ChrisWedgwood Bekerja lagi, Fiuh!
jtlz2
1
@ jtlz2 Saya beralih ke 3.7-slim-buster dan semuanya berjalan lancar di sana pythonspeed.com/articles/base-image-python-docker-images
xristian
9

PERHATIAN
Lihat jawaban @ jtlz2 dengan update terbaru

KELUAR

Jadi, paket py3-pandas & py3-numpy dipindahkan ke repositori alpine pengujian, jadi, Anda dapat mengunduhnya dengan menambahkan baris berikut ke Dockerfile Anda:

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

Semoga membantu seseorang!

Tautan paket Alpine:
- py3-pandas
- py3-numpy

Repositori Alpine menyimpan info .

stefanitsky
sumber
Ini berhasil untuk saya! Terima kasih telah memberikan jawaban yang diperbarui!
Stratus3D
2
Diperbaiki dalam jawaban saya
jtlz2
1
@ jtlz2 keren, terima kasih, tetapi saya pindah ke buster debian daripada alpine dan tidak mencoba menginstalnya lagi dengan alpine, tetapi bagaimanapun, terima kasih atas balasannya, juga memperbaiki jawaban saya
stefanitsky
1
Hanya untuk dicatat bahwa py3-pandas tidak tersedia untuk 3.11.x, ini hanya ada di rilis 'edge' pada saat saya menulis komentar ini. edit: Jelas dikatakan bahwa dalam posting di atas, saya baru saja melewatkan referensi itu sebelumnya, maaf.
busuk
6

Hanya akan menyatukan beberapa jawaban ini dalam satu jawaban dan menambahkan detail yang menurut saya terlewatkan. Alasan mengapa pustaka python tertentu, khususnya pustaka matematika dan data yang dioptimalkan, membutuhkan waktu lama untuk dibangun di atas alpine adalah karena roda pip untuk pustaka ini menyertakan biner yang telah dikompilasi sebelumnya dari c / c ++ dan ditautkan ke glibc, satu set pustaka standar c yang umum. Debian, Fedora, CentOS semua (biasanya) digunakan glibc, tetapi alpine, agar tetap ringan, gunakan musl-libcsebagai gantinya. c / c ++ binari yang dibangun di atas glibcsistem tidak akan berfungsi pada sistem yang tanpanya glibcdan hal yang sama berlaku untuk musl.

Pip pertama-tama mencari roda dengan binari yang benar, jika tidak dapat menemukannya, ia mencoba mengompilasi binari dari sumber c / c ++ dan menautkannya ke musl. Dalam banyak kasus, ini bahkan tidak akan berfungsi kecuali Anda memiliki header python dari python3-devatau membangun alat seperti make.

Sekarang lapisan peraknya, seperti yang telah disebutkan orang lain, ada apkpaket dengan binari yang tepat yang disediakan oleh komunitas, menggunakan ini akan menghemat Anda (terkadang panjang) proses membangun binari.

ThisGuyCantEven
sumber
6

Saran jujur ​​nyata di sini, beralih ke gambar berbasis Debian dan kemudian semua masalah Anda akan hilang.

Alpine untuk aplikasi python tidak bekerja dengan baik.

Berikut ini contoh my 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

The python:3.7.6-busterlebih tepat dalam hal ini, di samping itu, Anda tidak perlu ketergantungan tambahan di OS.

Ikuti artikel berguna dan terbaru: https://pythonspeed.com/articles/alpine-docker-python/ :

Jangan gunakan gambar Alpine Linux untuk Python Kecuali Anda ingin waktu pembuatan yang jauh lebih lambat, gambar yang lebih besar, lebih banyak pekerjaan, dan potensi bug yang tidak jelas, Anda sebaiknya menghindari Alpine Linux sebagai gambar dasar. Untuk beberapa rekomendasi tentang apa yang harus Anda gunakan, lihat artikel saya tentang memilih gambar dasar yang baik.

Flávio Henrique
sumber
2
Anda dapat mengurangi jumlah lapisan pada gambar Anda yaitu RUN pip install <packegeA> && pip install <packageB> dan seterusnya daripada menggunakan blok perintah RUN. Ini memengaruhi performa build Anda :)
p0l00ck
1
Anda juga bisa menggunakan pip --no-cacheuntuk mencukur sedikit lebih banyak jejak kaki. Apa yang harus Anda lakukan hanyalah meletakkannya baris demi baris dalam sebuah requirements.txtfile danpip install --no-cache -r requirements.txt
ThisGuyCantEven
1

Ini berhasil untuk saya:

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" ]

Sebagian besar kode di sini berasal dari jawaban jtlz2 dari utas yang sama dan Faylixe dari utas lain.

Ternyata versi panda yang lebih ringan ditemukan di repositori Alpine py3-numpytetapi tidak diinstal di jalur file yang sama dari tempat Python membaca impor secara default. Oleh karena itu, Anda perlu menambahkan file ENV. Juga perhatikan versi alpine.

Bishwas Mishra
sumber
0

pandasdianggap sebagai paket yang didukung komunitas, jadi jawaban yang ditunjukkan edge/testingtidak akan berfungsi karena Alpine tidak secara resmi mendukung panda sebagai paket inti (masih berfungsi, hanya saja tidak didukung oleh pengembang inti Alpine).

Coba Dockerfile ini:

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

Ini berfungsi untuk gambar vanilla Alpine juga, menggunakan FROM alpine:3.12.

Tingkat Z4
sumber
-1

alpine membutuhkan banyak waktu untuk memasang panda dan ukuran gambarnya juga besar. Saya mencoba python: versi 3.8-slim-buster dari gambar dasar python. Pembuatan gambar sangat cepat dan ukuran gambar kurang dari setengah dibandingkan dengan gambar buruh pelabuhan python alpine

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

Mukund Sharma
sumber