AlpineLinuxにPandasをインストールするのに何年もかかるのはなぜですか


103

ベースOSのAlpineとCentOSまたはDebianを使用してDockerコンテナにPandasとNumpy(依存関係)をインストールするのにはるかに時間がかかることに気づきました。以下に、時差を示すための小さなテストを作成しました。AlpineがPandasとNumpyをインストールするためにビルドの依存関係を更新およびダウンロードするのにかかる数秒を除いて、setup.pyがDebianのインストールよりも約70倍長い時間がかかるのはなぜですか?

Alpineをベースイメージとして使用してインストールを高速化する方法はありますか、またはPandasやNumpyなどのパッケージに使用するのに適したAlpineに匹敵するサイズの別のベースイメージがありますか?

Dockerfile.debian

FROM python:3.6.4-slim-jessie

RUN pip install pandas

Pandas&NumpyでDebianイメージをビルドします。

[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= *パンダ&ブランチ=エッジ
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、アルパインプラットフォームに基づく画像ではサポートされていません。そのためpython pip、ビルドプロセス中にを使用してインストールする場合は、常にアルパインのソースファイルからコンパイルします。

  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

残念ながら、pandasAlpineイメージにインストールする唯一の方法は、ビルドが完了するまで待つことです。

もちろんpandas、たとえばCIでAlpineイメージを使用する場合、そのための最善の方法は、一度コンパイルして任意のレジストリにプッシュし、必要に応じてベースイメージとして使用することです。

編集: アルパイン画像を一緒に使用したい場合はpandas、私のnickgryg / alpine-pandasdocker画像をプルできます。これはpandas、AlpineプラットフォームでプリコンパイルされたPythonイメージです。それはあなたの時間を節約するはずです。


3
まあ、それは残念です。ただし、6、pytz、およびpython-dateutilがAlpineに.whlパッケージをダウンロードしているようです。それは、パンダ用のホイールとアルパイン用のnumpyを構築することは可能ですが、それは現在行われていないということですか?
moku 2018年

いいえ、高山のプラットフォーム用pandasおよびそのnampy上にホイールを作成することはできません。それらのホイールはそれをサポートしていません。答えの中で、pandas高山のイメージでホイールパッケージからインストールしようとしたときにそれを示しました。
nickgryg 2018年

@Nickolayリサイクルする回避策の方法がありpandas、ビルドしている上に構築されalpine、その後、キャッシュされましたの?(これはローカルのどこかでホストされる可能性があります)
jtlz2 2018年

2
これがこの方法である理由は、これらのホイールにはc / c ++からビルドされ、glibcにリンクされたバイナリが含まれていますが、alpineにはglibcがなく、代わりにmuslを使用しているためです。つまり、新しいバイナリをコンパイルしてmuslに対してリンクする必要があります。
ThisGuyCantEven

36

回答:2020年3月9日の時点で、PYTHON 3の場合、まだ機能していません。

完全に機能するDockerfileは次のとおりです。

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

ビルドは正確なPythonとAlpineのバージョン番号に非常に敏感です-これらを間違えるとMaxLevyのエラーが発生するようです so:libpython3.7m.so.1.0 (missing)がするようです-しかし、上記は今ではうまくいきます。

更新されたDockerfileは、https: //gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13bで入手できます


[以前の更新:]

答え:そうではありません!

どのAlpineDockerfileでも、簡単に実行できます*

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

これはnumpyscipypandas上のすべての利用可能な構築済みです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一度ビルドして、Dockerfile内の好きな場所で使用できます:)

これにより、事実の前に他のすべてをDockerイメージにベイクする必要もなくなります。つまり、好きなDockerイメージを事前に構築する柔軟性があります。

PS私はhttps://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13bにDockerfileスタブを配置しました。これはイメージの構築方法を大まかに示しています。これらには重要なステップ(*)が含まれます:

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パッケージはテスト用のアルパインリポジトリに移動されたため、Dockerfileに次の行を追加してダウンロードできます。

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

それが誰かを助けることを願っています!

アルパインパッケージリンク:
- PY3 -パンダ
- PY3-numpyの

アルパインリポジトリドック情報


これは私のために働いた!更新された回答を提供していただきありがとうございます。
Stratus3D

2
私の答えで修正
jtlz2

1
jtlz2クール、おかげで、私は代わりに高山のDebianのバスターに移動してdidntのは、高山で再びそれをインストールしようとしたが、いずれにせよ、返信用のおかげで、また私の答え固定@
stefanitsky

1
py3-pandasは3.11.xでは使用できないことに注意してください。このコメントを書いている時点では、「エッジ」リリースのみです。編集:明らかに、上記の投稿では、申し訳ありませんが、以前にその参照を見逃したと言っています。
腐った

5

これらの回答のいくつかを1つの回答にまとめて、見逃したと思う詳細を追加するだけです。特定のPythonライブラリ、特に最適化された数学ライブラリとデータライブラリの構築に時間がかかる理由は、これらのライブラリのpipホイールに、c / c ++からプリコンパイルglibcされ、c標準ライブラリの一般的なセットに対してリンクされたバイナリが含まれているためです。Debian、Fedora、CentOSはすべて(通常)を使用しますがglibc、軽量を維持するためにアルパインがmusl-libc代わりに使用します。glibcシステム上に構築されたc / c ++バイナリは、システムなしでは機能しません。glibc同じことがmusl。にも当てはまります。

Pipは、最初に正しいバイナリを持つホイールを探します。見つからない場合は、c / c ++ソースからバイナリをコンパイルし、muslに対してリンクしようとします。多くの場合、からのpythonヘッダーがあるpython3-devか、のようなツールをビルドしない限り、これは機能しませんmake

現在、他の人が言及しているように、銀色の裏地にはapk、コミュニティによって提供される適切なバイナリを含むパッケージがあります。これらを使用すると、バイナリを構築する(場合によっては長い)プロセスを節約できます。


5

ここでの本当の正直なアドバイスは、Debianベースのイメージに切り替えると、すべての問題が解消されます。

Pythonアプリケーション用のAlpineはうまく機能しません。

これが私の例です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加えて、あなたはOSに余分な依存関係を必要としない、この場合はより適切です。

便利で最近の記事に従ってください:https//pythonspeed.com/articles/alpine-docker-python/

PythonイメージにAlpineLinuxを使用しないでくださいビルド時間が大幅に遅くなり、イメージが大きくなり、作業量が増え、バグが不明瞭になる可能性がない限り、AlpineLinuxをベースイメージとして使用しないでください。何を使用すべきかについてのいくつかの推奨事項については、適切なベースイメージの選択に関する私の記事を参照してください。


1
RUNコマンドのブロックを使用する代わりに、イメージ内のレイヤーの数を減らすことができます。つまり、RUN pip install <packegeA> && pip install <packageB>などです。ビルドのパフォーマンスに影響します:)
p0l00ck

pip --no-cacheフットプリントをもう少し削るのにも使用できます。あなたが本当にすべきことは、それらを1行requirements.txtpip install --no-cache -r requirements.txt
ずつ

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/testingAlpineはパンダをコアパッケージとして公式にサポートしていないため、を指す回答は機能しません(引き続き機能し、コアのAlpine開発者によってサポートされていないだけです)。

このDockerfileを試してください:

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ます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.