Dockerfile优化推荐
容器镜像服务CCR企业版支持基于Dockerfile构建新的容器镜像,按照Dockerfile优化推荐最佳实践可以帮助您找出Dockerfile中的潜在问题、提高镜像构建效率和容器镜像的质量。
相关概念
Dockerfile:一种用来构建镜像的文本文件,内容包含了构建镜像过程中所需的指令、依赖项列表和一些重要的说明。关于Dockerfile的语法详细说明参见 Docker官网dockerfile。
精简基础镜像
精简基础镜像 可以有效减少镜像拉取的时长,提升镜像运行的效率。DockerHub 中存储的镜像文件可能包含应用不必要的依赖数据。您可以考虑使用社区中其他更小的镜像文件,或者基于 Docker 的最小架构,构建您自己最小可用的基础镜像。
关于基础镜像的详细说明参见 Docker官网文档 Baseimages。
为基础镜像设置标签
引用基础镜像,但是不设置镜像标签(Tag)时,默认使用 latest (最新)版本的镜像文件。 随着时间的推移, latest 版本极大可能会发生变更,从而导致您在后续的推拉镜像时,整个镜像的重构,提升了镜像构建的时间成本。
- 优化前
1 FROM nginx
2
3 ADD . /app
4 RUN cd /app && booking install
5
6 CMD booking start
- 优化后
1 FROM nginx:1.25
2
3 ADD . /app
4 RUN cd /app && booking install
5
6 CMD booking start
后置高频变化的指令
尽可能的缩短重构镜像并上传镜像层所需的时间,可以将最稳定的依赖保存在 Dockerfile 中。将变更频率较高的依赖(例如您应用程序的原始代码)靠后存放。
Docker 会缓存镜像分层文件,以便加速镜像的构建。如果本次的构建的镜像相较上次没有变化,Docker 不会重构镜像,而是直接使用已缓存的镜像版本,有效节省了镜像构建的时间。但是,每个镜像层都依赖于前一个镜像层。如果前一个镜像层发生了变化,即使当前镜像层未发生变化,当前镜像层也会被重构。将变更频率较高的依赖靠后放置可以减少镜像重构的层数。
例如示例中 booking 模块的变更的频率比较 nodejs 高,那么执行 booking 的指令应该放置在后方。
- 优化前
1 FROM nginx
2
3 ADD . /app
4 RUN cd /app && booking install
5 RUN apt-get update && apt-get install -y nodejs
6
7 CMD booking start
- 优化后
1 FROM nginx:1.25
2
3 RUN apt-get update && apt-get install -y nodejs
4 ADD . /app
5 RUN cd /app && booking install
6
7 CMD booking start
使用合并的指令
通过合并的指令可以将不需要的中间产物文件有效的删除,精简镜像的容量。
上一行指令创建的文件,即使在后续的指令行中删除,依然会作为镜像的一部分,占据镜像文件的容量,只是在 Docker 容器中不可见。
- 优化前
1 WORKDIR /tmp
2 RUN wget http://booking.com/booking.tar.gz
3 RUN wget tar -xvf booking.tar.gz
4 RUN mv booking/binary /opt/bin/myapp
5 RUN rm booking.tar.gz
- 优化后
1 WORKDIR /tmp
2 RUN wget http://booking.com/booking.tar.gz &&\
3 wget tar -xvf booking.tar.gz &&\
4 mv booking/binary /opt/bin/myapp &&\
5 rm booking.tar.gz
