我注意到使用基本操作系统Alpine与CentOS或Debian在Docker容器中安装Pandas和Numpy(它的依赖关系)需要更长的时间。我在下面创建了一个小测试来演示时差。除了Alpine更新和下载构建依赖项以安装Pandas和Numpy的几秒钟之外,为什么setup.py需要的时间比Debian安装多70倍?
有没有办法加速安装使用Alpine作为基本图像,或者是否有另一个与Alpine相当的基本图像,最好用于像Pandas和Numpy这样的包?
Dockerfile.debian
FROM python:3.6.4-slim-jessie
RUN pip install pandas
使用Pandas& amp;构建Debian图像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& amp;构建高山图像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
答案 0 :(得分:32)
基于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文件只需要移动到要安装的目标系统上的正确位置,而源分发需要在安装之前进行构建步骤。
基于Alpine平台的图片不支持Wheel包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
不幸的是,在Alpine图像上安装pandas
的唯一方法是等到构建完成。
当然,如果您想在CI中使用带有pandas
的Alpine图像,最好的方法是编译一次,将其推送到任何注册表并将其用作您的基本图像需要。
修改强>
如果您想将Alpine图像与pandas
一起使用,则可以提取我的nickgryg/alpine-pandas泊坞窗图像。它是一个在Alpine平台上预编译pandas
的python图像。它应该节省你的时间。
答案 1 :(得分:8)
[更新:]
答案:它没有!
在任何Alpine Dockerfile中,您只需执行
numpy
这是因为scipy
预设的pandas
,alpine
和现在.apk
全部可用:
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
您可以构建这些def setup
user = users(:default_user)
@post = Post.new(
title: "Hello World",
body: "Hello world, it's nice to meet you",
user: user
)
end
一次,并在您喜欢的Dockerfile中的任何位置使用它们。)
这也可以节省您在事实之前将其他所有内容都烘焙到Docker镜像中的过程 - 即可以灵活地预先构建您喜欢的任何Docker镜像。
答案 2 :(得分:6)
这里是真实的忠实建议,切换到基于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
更合适,此外,您在操作系统中不需要任何额外的依赖关系。
关注有用的最新文章:https://pythonspeed.com/articles/alpine-docker-python/:
请勿将Alpine Linux用于Python映像 除非您希望大幅降低构建时间,增加图像尺寸,增加工作量以及潜在的隐蔽错误,否则您将避免使用Alpine Linux作为基础图像。有关应使用什么的一些建议,请参阅我的文章,有关选择一个好的基本图像。
答案 3 :(得分:5)
注意
查看具有最新更新的@ jtlz2答案
2019年9月17日最新更新
因此,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-pandas
-py3-numpy高山仓库docks info。
答案 4 :(得分:2)
只需将其中的一些答案汇总到一个答案中,并添加我认为错过的细节即可。某些python库(尤其是经过优化的数学和数据库库)在alpine上构建需要花费很长时间的原因是因为这些库的pip wheel包括从c / c ++预编译并与glibc
(一组通用的c标准)链接的二进制文件库。 Debian,Fedora和CentOS都(通常)都使用glibc
,而阿尔卑斯山为了保持轻便,而使用musl-libc
。在glibc
系统上构建的c / c ++二进制文件在没有glibc
的系统上将不起作用,并且musl
也是如此。
Pip首先寻找具有正确二进制文件的转轮,如果找不到,它将尝试从c / c ++源代码编译二进制文件并将其与musl链接。在许多情况下,除非您拥有python3-dev
中的python标头或构建诸如make
之类的工具,否则这什至不起作用。
现在,就像其他人提到的那样,一线希望是,有apk
个软件包由社区提供了正确的二进制文件,使用这些软件包将节省您(有时是冗长的)构建二进制文件的过程。
答案 5 :(得分: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
。另外请注意高山版本。
答案 6 :(得分:0)
pandas
被认为是社区支持的软件包,因此指向edge/testing
的答案将不起作用,因为Alpine并未正式支持将熊猫作为核心软件包(它仍然有效,只是不被支持)由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
,这也适用于原始的Alpine图片。
答案 7 :(得分:0)
在这种情况下,高山不是最好的解决方案,将高山改为苗条:
改为:
FROM python:3.8.3-slim
就我而言,这个小改动就解决了。
答案 8 :(得分:-1)
高山需要花费大量时间来安装熊猫,而且图像尺寸也很大。我尝试了python:3.8-slim-buster版本的python基本映像。与高山python docker图像相比,图像构建速度非常快,并且图像尺寸不到一半。
https://github.com/dguyhasnoname/k8s-cluster-checker/blob/master/Dockerfile