[英]How minimize python3.7 application docker image
我想用这个Dockerfile
对接 python 程序:
FROM python:3.7-alpine
COPY requirements.pip ./requirements.pip
RUN python3 -m pip install --upgrade pip
RUN pip install -U setuptools
RUN apk update
RUN apk add --no-cache --virtual .build-deps gcc python3-dev musl-dev openssl-dev libffi-dev g++ && \
python3 -m pip install -r requirements.pip --no-cache-dir && \
apk --purge del .build-deps
ARG APP_DIR=/app
RUN mkdir -p ${APP_DIR}
WORKDIR ${APP_DIR}
COPY app .
ENTRYPOINT [ "python3", "run.py" ]
这是我的requirements.pip
文件:
pysher~=0.5.0
redis~=2.10.6
flake8~=3.5.0
pandas==0.23.4
由于 pandas,docker 图像有 461MB,没有 pandas 131MB。
我在想如何让它更小,所以我从我的应用程序中构建二进制文件:
pyinstaller run.py --onefile
它构建了 38M 的二进制文件。 当我运行它时,它工作正常。 所以我从Dockerfile
构建 docker 图像:
FROM alpine:3.4
ARG APP_DIR=/app
RUN mkdir -p ${APP_DIR}
WORKDIR ${APP_DIR}
COPY app/dist/run run
ENTRYPOINT [ "/bin/sh", "/app/run" ]
基本上,只是将我的run
二进制文件复制到/app
目录中。 看起来不错,图像只有 48.8MB。 当我运行容器时,我收到错误:
$ docker run --rm --name myapp myminimalimage:latest
/app/run: line 1: syntax error: unexpected "("
然后我在想,也许sh
有问题,所以我安装了bash
,所以我在Dockerfile
中添加了3行:
RUN apk update
RUN apk upgrade
RUN apk add bash
图像已构建,但当我运行它时再次出现错误:
$ $ docker run --rm --name myapp myminimalimage:latest
/app/run: /app/run: cannot execute binary file
我的问题:
为什么第一步的图像这么大? 我可以以某种方式最小化尺寸吗? 喜欢从 pandas package 中选择安装什么?
为什么我的二进制文件在我的系统(Kubuntu 18.10)上运行良好,但我无法从alpine:3.4
运行它,我应该使用另一个图像还是安装一些东西来运行它?
使用我的应用程序构建简约图像的最佳方法是什么? 上面提到的一种还是有其他方法?
在大小上,确保在使用pip
时始终传递--no-cache-dir
(使用一次,但在其他情况下不使用)。 同样,结合使用apk
并确保最后一步是清除apk
缓存,使其永远不会在图像层中冻结,例如,将三个单独的RUN
替换为RUN apk update && apk upgrade && apk add bash && rm -rf /var/cache/apk/*
; 在单层中达到相同的效果,不会保留apk
缓存。
例子:
FROM python:3.7-alpine
COPY requirements.pip ./requirements.pip
# Avoid pip cache, use consistent command line with other uses, and merge simple layers
RUN python3 -m pip install --upgrade --no-cache-dir pip && \
python3 -m pip install --upgrade --no-cache-dir setuptools
# Combine update and add into same layer, clear cache explicitly at end
RUN apk update && apk add --no-cache --virtual .build-deps gcc python3-dev musl-dev openssl-dev libffi-dev g++ && \
python3 -m pip install -r requirements.pip --no-cache-dir && \
apk --purge del .build-deps && rm -rf /var/cache/apk/*
不要指望它会做很多事情(您已经在大型pip
操作中使用了--no-cache-dir
),但它确实有用。 pandas
是一个巨大的单片package,依赖于其他巨大的单片封装; 您可以在这里完成的工作是有限度的。
请记住,如果您不使用 Alpine,则不需要编译器,因为您可以只使用轮子。 这使一切变得更简单......例如,您不需要安装然后卸载编译器。 稍微大一点,但只有一点点。
(请参阅此处了解为什么我不是 Alpine Linux 的粉丝: https://pythonspeed.com/articles/base-image-python-docker-images/ )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.