1. 分阶段构建
编译项目需要借助一系列特定的工具,但在运行阶段并不需要这些工具。为了减小镜像体积,可以分阶段构建。在第一阶段进行构建,然后将编译生成的文件传入下一个阶段,生成更小体积的镜像。
|
|
上面是一个编译 Go 工程镜像的 Dockerfile 文件。很多项目选择 alpine 作为基础镜像。但是,如果项目使用到系统的某些库,基础镜像不能随意选择。
2. 利用缓存构建
Docker 镜像是分层的结构,最多 127 层。除了 FROM
命令,Dockerfile 中其他命令都会生成一个新的镜像层。在构建过程中,如果发现命令将产生的镜像层与之前的一样,则会使用缓存复用。
为了利用缓存加速构建过程,可以将静态和配置命令放在前面,而将经常变化的内容放在后面。
|
|
由于项目工程代码每次构建时,总会发生变化,应该尽量放在底部;依赖包不会经常发生变化,放在上面可以充分利用缓存。
使用下面的构建命令,可以禁用缓存:
|
|
3. 使用 S2I 打包应用
相对于使用缓存优化构建速度,更加简单的方式是,使用 S2I 打包应用,增加一层镜像即可。
参考链接:使用 S2I 构建云原生应用
没有被 S2I 支持的语言或框架也没关系,我们可以将应用所需的基础环境打包成基础镜像,然后再进行构建。
4. .dockerignore 文件
Docker 以 C/S
模型进行工作,在执行构建时,会将所需的文件发送到 Docker Daemon 。有些很大、构建用不上的文件,会占用传输时间,我们可以定义 .dockerignore
忽略这些文件,就像 .gitignore
一样。
.dockerignore 文件
.git
Dockerfile 文件
|
|
上面的例子,COPY
时会忽略 .git
目录。
5. 将容器保存为镜像
在学习 Docker 时,经常会被教育不要在容器中做任何修改。这句话没错,遵循不可变的基础设施。
除了打包镜像,我们会直接进入容器进行调试。有时因为历史原因,找不到镜像或 Dockerfile 文件,需要将容器保存为镜像。
执行 docker commit
命令,可以将 ContainerID
保存为 shaowenchen/myimage:latest
镜像。
|
|