Tại sao phải mất nhiều thời gian để cài đặt Pandas trên Alpine Linux


103

Tôi nhận thấy rằng việc cài đặt Pandas và Numpy (đó là sự phụ thuộc) trong vùng chứa Docker bằng hệ điều hành cơ sở Alpine so với CentOS hoặc Debian mất nhiều thời gian hơn. Tôi đã tạo một bài kiểm tra nhỏ bên dưới để chứng minh sự khác biệt về thời gian. Ngoài vài giây Alpine mất để cập nhật và tải xuống các bản dựng phụ thuộc để cài đặt Pandas và Numpy, tại sao setup.py lại mất nhiều thời gian hơn 70 lần so với cài đặt trên Debian?

Có cách nào để tăng tốc cài đặt bằng cách sử dụng Alpine làm hình ảnh cơ sở hoặc có hình ảnh cơ sở khác có kích thước tương đương với Alpine tốt hơn để sử dụng cho các gói như Pandas và Numpy không?

Dockerfile.debian

FROM python:3.6.4-slim-jessie

RUN pip install pandas

Xây dựng hình ảnh Debian với 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

Xây dựng hình ảnh Alpine với 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 hiện có sẵn, vì vậy không cần xây dựng từ nguồn - pkgs.alpinelinux.org/packages?name= * pandas & branch = edge
jtlz2 24/02/19

1
@ jtlz2, gấu trúc không có ở rìa nhánh của Alpine. thật đáng tiếc ...
fccoelho

@fccoelho Hiện đã có lại!
jtlz2

Câu trả lời:


65

Hình ảnh dựa trên Debian chỉ sử dụng python pipđể cài đặt các gói có .whlđịnh dạng:

  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)

Định dạng WHL được phát triển như một phương pháp cài đặt phần mềm Python nhanh chóng và đáng tin cậy hơn là xây dựng lại từ mã nguồn mọi lúc. Các tệp WHL chỉ phải được di chuyển đến đúng vị trí trên hệ thống đích để được cài đặt, trong khi bản phân phối nguồn yêu cầu một bước xây dựng trước khi cài đặt.

Gói bánh xe pandasnumpykhông được hỗ trợ trong hình ảnh dựa trên nền tảng Alpine. Đó là lý do tại sao khi chúng tôi cài đặt chúng bằng cách sử dụng python piptrong quá trình xây dựng, chúng tôi luôn biên dịch chúng từ các tệp nguồn trong alpine:

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

và chúng ta có thể thấy vùng chứa bên trong sau trong quá trình xây dựng hình ảnh:

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

Nếu chúng ta sửa đổi Dockerfilemột chút:

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

chúng tôi gặp lỗi sau:

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

Thật không may, cách duy nhất để cài đặt pandastrên ảnh Alpine là đợi cho đến khi quá trình xây dựng hoàn tất.

Tất nhiên nếu bạn muốn sử dụng hình ảnh Alpine với pandastrong CI chẳng hạn, cách tốt nhất để làm như vậy là biên dịch nó một lần, đẩy nó vào bất kỳ sổ đăng ký nào và sử dụng nó làm hình ảnh cơ sở cho nhu cầu của bạn.

CHỈNH SỬA: Nếu bạn muốn sử dụng hình ảnh Alpine, pandasbạn có thể kéo hình ảnh docker nickgryg / alpine-pandas của tôi . Nó là một hình ảnh con trăn được biên dịch sẵn pandastrên nền tảng Alpine. Nó sẽ tiết kiệm thời gian của bạn.


3
Chà, tệ quá. Tuy nhiên, có vẻ như sáu, pytz và python-dateutil đang tải xuống các gói .whl trên Alpine. Điều đó có nghĩa là có thể chế tạo bánh xe cho gấu trúc và bánh xe cho Alpine, nhưng điều đó hiện chưa xảy ra?
moku

Không, không thể chế tạo bánh xe cho pandasnampytrên nền tảng núi cao. Những bánh xe đó không hỗ trợ nó. Tôi đã cho thấy điều đó trong câu trả lời, khi cố gắng cài đặt pandastừ gói bánh xe của nó trong hình ảnh núi cao.
nickgryg

@Nickolay Có cách giải quyết nào để tái chế một bản pandasdựng đã được xây dựng alpinevà sau đó được lưu vào bộ nhớ đệm không? (điều này có thể được tổ chức ở đâu đó tại địa phương)
jtlz2

2
Lý do là theo cách này vì các bánh xe này chứa các tệp nhị phân được xây dựng từ c / c ++ và được liên kết với glibc, nhưng alpine không có glibc, thay vào đó nó sử dụng musl, có nghĩa là các tệp nhị phân mới phải được biên dịch và liên kết với musl.
ThisGuyCantEven

36

TRẢ LỜI: Kể từ ngày 3/9/2020, ĐỐI VỚI PYTHON 3, NÓ VẪN KHÔNG CÓ!

Đây là một Dockerfile đang hoạt động hoàn chỉnh:

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

Bản dựng rất nhạy cảm với số phiên bản python và alpine chính xác - nhận sai những con số này có vẻ như gây ra lỗi của Max Levy so:libpython3.7m.so.1.0 (missing)- nhưng những điều trên giờ đã hoạt động với tôi.

Dockerfile cập nhật của tôi có sẵn tại https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b


[Cập nhật trước đó:]

TRẢ LỜI: KHÔNG ĐƯỢC!

Trong bất kỳ tệp Alpine Dockerfile nào, bạn chỉ cần thực hiện *

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

Điều này là do numpy, scipyvà bây giờ pandastất cả đều được xây dựng sẵn có sẵn trên 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

Một cách để tránh phải xây dựng lại mọi lần hoặc sử dụng lớp Docker là sử dụng gói / .apkgói Alpine Linux được xây dựng trước , ví dụ:

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

https://github.com/nbgallery/apks

Bạn có thể xây dựng những cái này .apkmột lần và sử dụng chúng ở bất cứ đâu trong Dockerfile mà bạn thích :)

Điều này cũng giúp bạn tiết kiệm việc phải nướng mọi thứ khác vào hình ảnh Docker trước khi thực tế - tức là sự linh hoạt để xây dựng trước bất kỳ hình ảnh Docker nào bạn thích.

PS Tôi đã đặt một bản gốc Dockerfile tại https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b cho thấy đại khái cách xây dựng hình ảnh. Chúng bao gồm các bước quan trọng (*):

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
Có vẻ như nó đã bị xóa gần đây? pkgs.alpinelinux.org/package/edge/testing/x86/py-pandas
jtlz2 19/03/19

1
@ChrisWedgwood Họ đang tích cực làm việc trên đó - xem github.com/alpinelinux/aports/pull/6330
jtlz2 19/03/19

1
@ChrisWedgwood Đang hoạt động trở lại, phew!
jtlz2


1
@ jtlz2 Tôi đã chuyển sang 3.7-slim-buster và mọi thứ diễn ra suôn sẻ ở đó pythonspeed.com/articles/base-image-python-docker-images
xristian

9

CHÚ Ý
Xem câu trả lời @ jtlz2 với bản cập nhật mới nhất

NGOÀI RA

Vì vậy, các gói py3-pandas & py3-numpy đã được chuyển đến kho lưu trữ núi cao thử nghiệm, vì vậy, bạn có thể tải xuống bằng cách thêm các dòng này vào Dockerfile của bạn:

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

Hy vọng nó sẽ giúp một ai đó!

Liên kết các gói Alpine:
- py3-pandas
- py3-numpy

Thông tin kho lưu trữ Alpine cập bến .


Điều này đã làm việc cho tôi! Cảm ơn bạn đã cung cấp câu trả lời cập nhật!
Stratus3D

2
Cố định trong câu trả lời của tôi
jtlz2

1
@ jtlz2 mát mẻ, cảm ơn, nhưng tôi chuyển đến buster debian thay vì núi cao và didnt cố gắng cài đặt nó một lần nữa với núi cao, nhưng dù sao, nhờ trả lời, cũng cố định câu trả lời của tôi
stefanitsky

1
Chỉ cần lưu ý rằng py3-pandas không có sẵn cho 3.11.x, nó chỉ có trong bản phát hành 'cạnh' tính đến thời điểm tôi viết bình luận này. chỉnh sửa: Rõ ràng nó nói rằng trong bài đăng ở trên, tôi chỉ bỏ lỡ tài liệu tham khảo đó trước đó, xin lỗi.
thối

5

Tôi chỉ tập hợp một số câu trả lời này lại với nhau trong một câu trả lời và thêm một chi tiết mà tôi nghĩ đã bị bỏ sót. Lý do khiến một số thư viện python, đặc biệt là các thư viện dữ liệu và toán học được tối ưu hóa, mất nhiều thời gian để xây dựng trên alpine là vì bánh xe pip cho các thư viện này bao gồm các tệp nhị phân được biên dịch trước từ c / c ++ và được liên kết với glibcmột bộ thư viện tiêu chuẩn c phổ biến. Debian, Fedora, CentOS, tất cả (thường) đều sử dụng glibc, nhưng alpine, để giữ cho dung lượng nhẹ, sử dụng musl-libcthay thế. c / c ++ nhị phân được xây dựng trên một glibchệ thống sẽ không hoạt động trên một hệ thống không có glibcvà điều tương tự cũng xảy ra musl.

Trước tiên, Pip tìm kiếm một bánh xe có các mã nhị phân chính xác, nếu không tìm thấy mã này, nó sẽ cố gắng biên dịch các mã nhị phân từ nguồn c / c ++ và liên kết chúng với musl. Trong nhiều trường hợp, điều này thậm chí sẽ không hoạt động trừ khi bạn có tiêu đề python từ python3-devhoặc xây dựng các công cụ như make.

Bây giờ, lớp lót bạc, như những người khác đã đề cập, có apkcác gói với các tệp nhị phân thích hợp do cộng đồng cung cấp, việc sử dụng các gói này sẽ giúp bạn tiết kiệm (đôi khi kéo dài) quá trình xây dựng các tệp nhị phân.


5

Đây là lời khuyên trung thực, hãy chuyển sang hình ảnh dựa trên Debian và sau đó mọi vấn đề của bạn sẽ không còn nữa.

Ứng dụng Alpine cho python không hoạt động tốt.

Đây là một ví dụ của tôi 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

Các python:3.7.6-busterlà thích hợp hơn trong trường hợp này, ngoài ra, bạn không cần bất kỳ phụ thuộc thêm vào hệ điều hành.

Theo dõi bài viết hữu ích và gần đây: https://pythonspeed.com/articles/alpine-docker-python/ :

Không sử dụng Alpine Linux cho hình ảnh Python, trừ khi bạn muốn thời gian xây dựng chậm hơn nhiều, hình ảnh lớn hơn, nhiều công việc hơn và khả năng xuất hiện các lỗi khó hiểu, bạn sẽ muốn tránh Alpine Linux làm hình ảnh cơ sở. Để biết một số khuyến nghị về những gì bạn nên sử dụng, hãy xem bài viết của tôi về cách chọn hình ảnh cơ sở tốt.


1
Bạn có thể giảm số lớp trong hình ảnh của mình, tức là RUN pip install <packegeA> && pip install <packageB>, v.v. thay vì sử dụng một khối lệnh RUN. Nó ảnh hưởng đến hiệu suất xây dựng của bạn :)
p0l00ck

Bạn cũng có thể sử dụng pip --no-cacheđể cạo bớt một chút dấu chân. Những gì bạn thực sự nên làm là chỉ cần đặt chúng từng dòng trong một requirements.txttệp vàpip install --no-cache -r requirements.txt
ThisGuyCantEven

1

Điều này đã làm việc cho tôi:

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

Hầu hết mã ở đây là từ câu trả lời của jtlz2 từ cùng một chủ đề này và Faylixe từ một chủ đề khác.

Hóa ra phiên bản nhẹ hơn của gấu trúc được tìm thấy trong kho lưu trữ Alpine py3-numpynhưng nó không được cài đặt trong cùng đường dẫn tệp từ nơi Python đọc dữ liệu nhập theo mặc định. Do đó bạn cần thêm ENV. Cũng cần lưu ý về phiên bản núi cao.


0

pandasđược coi là một gói được cộng đồng hỗ trợ, vì vậy các câu trả lời trỏ đến edge/testingsẽ không hoạt động vì Alpine không chính thức hỗ trợ gấu trúc như một gói cốt lõi (nó vẫn hoạt động, chỉ là không được các nhà phát triển cốt lõi của Alpine hỗ trợ).

Hãy thử Dockerfile này:

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

Điều này cũng phù hợp với hình ảnh vani Alpine bằng cách sử dụng FROM alpine:3.12.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.