在这里以Python 举例
直接上对比
原始
******* latest 01360a9dec8f About an hour ago 1.05GB
改进后
****** latest 9e3b99fe9812 13 seconds ago 172MB
第一步 选用 正确的镜像
下面是部分官方镜像截图(截取自dockerhub)
可以看到 不同的tag 有的相差一二百MB 有些基于windows的镜像甚至高达5.4GB之巨! 所以 选用正确的镜像很重要. 这里建议使用基于alpine的Python Runtime镜像. 但是alpine 过于精简,少了很多基础软件 例如 gcc , 当安装某些需要编译的Python 包的时候就需要它.
第二步 如何正确的在构建镜像时 pip install
这里用到一些 Dockerfile 中的 Stage 概念. 和pip install 把包都安装到了哪里.
FROM docker pull python:3.8.3-alpine3.11 as Base
RUN apk --no-cache add curl
RUN curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_17.5.2.2-1_amd64.apk && \
apk add --allow-untrusted msodbcsql17_17.5.2.2-1_amd64.apk
FROM Base as Build
WORKDIR /src
RUN apk --no-cache add build-base
RUN curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_17.5.2.2-1_amd64.apk && \
apk add --allow-untrusted msodbcsql17_17.5.2.2-1_amd64.apk
WORKDIR /app
COPY ./requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt
FROM Base as Final
COPY --from=Build /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
WORKDIR /app
ENV CONFIGPATH=/config/config.cfg
EXPOSE 5001
VOLUME [ "/config" ]
COPY . /app
ENTRYPOINT ["python"]
CMD ["flaskapp.py"]
可以看到 在第1行和第5行 分别有两个FROM 对应着 Base 和 Build 两个Stage
Base , 负责安装 程序运行所必需的基础软件. 例如:这里我安装了MSSQL的 ODBC ,
Build, 负责安装 python 包, 由于某些Python 包需要使用gcc 进行编译, 先安装
alpine 官方的build-base , 接着将 requirements.txt 从本地 添加到 image 进行安装和编译
由于为了编译 安装了build-base中的编译工具,
但是这些工具显然在Python程序运行的时候是不需要的
所以在第 13 行 再次将 Base 作为基础镜像,
这个时候就可以甩开 前面安装的 build-base 只需要将 编译好的site-packages 复制进来就OK了
注意 第5行 和第13 行的FROM 仍然可以使用其他的镜像, 这意味着你甚至可以用 Python:3.8.3-buster这类SDK镜像 内置的gcc 进行编译 然后再 copy 到 Final Stage
例如:
FROM python:3.8.3-buster AS Build
总结
可以看出 一旦理解了 Dockerfile 中命令的作用, Dockerfile 本身还是非常 self-explained 的
网友评论