Docker知识
- 一个layer是一个改变,每个命令(RUN, COPY,)都会产生一个新的layer。
- 每个layer都有一个ID,Image之间可以复用相同的layer。
- 当更新时,若有layer不发生变化,不需要重新上传到registry
- docker history可以查看每个步骤产生的Layer大小。
优化案列
本文使用的image是基于python base image,安装一些必要软件后,提供Python的运行环境。
优化前的dockerfile
前面都是些安装软件,优化前最后的几个步骤为:
COPY . ${API_DIR}
RUN rm -rf ${API_DIR}/venv/
RUN set -x && \
source ${API_ENV_DIR}/bin/activate && pip install --upgrade --force-reinstall -r ${API_DIR}/requirements.txt
产生的问题:
每次更新一次源码,image会有500MB的变化,非常大,影响Image更新。
优化原则
- 经常变化的内容(如源码)尽量放到Dockerfile最后一步
优化步骤
- 去掉不必要的venv目录,减少文件夹大小。
- 把安装依赖库提到复制源码之前,这样如果依赖库不变,此layer就不会发生变化。
- 将复制源码放到最后一步,这样每次源码发生变化,只有最后一个layer变化。
调整后的dockerfile:
# requirments install before source data, this can save image layer
COPY requirements.txt ${API_DIR}/
RUN set -x && \
source ${API_ENV_DIR}/bin/activate && pip install --upgrade --force-reinstall -r ${API_DIR}/requirements.txt
COPY . ${API_DIR}
RUN rm -rf ${API_DIR}/venv/
WORKDIR /src/
效果
优化后每次更新源码需要推送Image更新只有13MB,而优化前是500MB