1. 利用Squash功能 (1.13 后新增的试验功能)
1、Docker Daemon 进程启动前,要将 experimental 参数设置为 true;
docker v20版本是通过修改/etc/docker/daemon.json
开启:
{
"experimental": true
}
2、编写的dockerfile没有与之前没有差异
3、编译时,增加--squash
参数
docker build --squash -t xxx:xxx .
squash功能一方面压缩了镜像的大小,另一方面保存了镜像的构建信息,但是该方法属于实验特性,需要谨慎使用。
2. 使用Alpine Linux
Alpine Linux是一个基于BusyBox和Musl Libc的Linux发行版,其最大的优势就是小。一个纯的基础Alpine Docker镜像在压缩后仅有2.67MB。
3. 只安装最少的依赖
apt-get、yum、apk等软件包管理器是我们编译镜像时必然需要用到的工具,纯净的Docker基础镜像通常会缺少wget、curl、git、gcc等工具,需要我们手工来安装。
我们以apt为例,apt-get在安装软件的时候,可以指定一个选项:–no-install-recommends,指定这个参数后,有一些非必须的依赖将不会被一起安装。比如,我们安装wget时,如果增加这个选项,待安装的包将从6个减少为3个:
4. 尽量将中间依赖的安装与卸载操作放在一个步骤中
docker镜像是一个由“层”来堆叠起来的“千层饼”,我们可以使用docker history 这条命令来查看任意一个镜像是由哪些层组成的,以及每一层的大小:
对于Dockerfile来说,这些层的数据都将会被保存在镜像中,即使后一层删除了前一层内保存的文件。
比如,我们有如下Dockerfile:
FROM alpine:3.12
RUN truncate -s 50M /sample.dat
RUN rm -rf /sample.dat
我们可以试试看这个镜像编译出来有多大,58MB:
相比起来,正常的alpine:3.12只有5.57MB,说明即使我们已经删除了/sample.dat文件,在最后的镜像中也没有这个内容,但是它永远留在了镜像的history中。
所以,在删除上文说到的“中间依赖”时,我们需要将安装、使用、卸载三个部分写在一个步骤中,才能保证空间被释放。比如:
所以,在删除上文说到的“中间依赖”时,我们需要将安装、使用、卸载三个部分写在一个步骤中,才能保证空间被释放。比如:
FROM debian:buster
RUN apt-get update \
&& apt-get install gcc \
&& gcc … \
&& apt-get purge –autoremove gcc \
&& rm -rf /var/lib/apt/lists/*